home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / pao / towns / cdplay / src / cdda.c next >
C/C++ Source or Header  |  1991-10-18  |  103KB  |  2,808 lines

  1. /* << High C V1.4 >> **********************************************************
  2. **
  3. **    CD演奏ライブラリ
  4. **
  5. **    1991.02.09 : CREATE
  6. **    1991.02.13 : FINISH
  7. **
  8. **    < HISTORY >
  9. **    1991.02.09 : CREATE
  10. **    1991.02.19 : SHUFFLE機能の追加.
  11. **    1991.02.27 : 全面改訂開始....
  12. **    1991.03.23 : 全面改訂終了(新ライブラリ誕生)
  13. **    1991.03.25 : PROGRAM演奏モードままCDを入れ換えた時に、未選択合計時間
  14. **                 の値がおかしくなるのを修正. (tocread()内で設定するよう変更)
  15. **    1991.03.29 : PROGRAM演奏モード時に最後の演奏曲を演奏中に削除した時に、登録
  16. **                 曲を全てクリアしていたのを仕様変更し、リピート設定がなければ クリア 
  17. **                 するようにした.
  18. **    1991.03.31 : 演奏できなかった時に、NOT READY にしていたのを パラメタエラー に
  19. **                 なるよう修正した.
  20. **    1991.04.19 : 初期処理時に演奏中だった場合にTOC情報取得後の演奏開始時間が
  21. **                 曲の先頭になっていたのを続きの時間になるよう修正.
  22. **    1991.06.07 : 清書
  23. **
  24. **    < note > : TABS = 4
  25. **
  26. **    All Rights Reserved, Copyright (C) Y.Hirata 1991.
  27. **
  28. **    Programmed by Y.Hirata ( Nifty ID : NAB03321 )
  29. **
  30. ******************************************************************************/
  31.  
  32. pragma    Off (Floating_point) ;
  33.  
  34. #define    _CDDA_LIB
  35.  
  36. #include <cdr.h>
  37. #include <string.h>
  38. #include <stdio.h>
  39. #include <stdlib.h>
  40. #include <time.h>
  41. #include "cdda.h"
  42.  
  43. char    *COPYRIGHT = "CDDA LIBRARY v1.00 1991.06.07  Copyright (C) Y.Hirata 1991. " ;
  44.  
  45. /*-----------------------------------------------------------------------------
  46. **    CDDA.LIB 解説
  47. **
  48. **    主な関数では、初期化ルーチンが呼ばれたかどうかチェックし、必ず呼ぶようにしてます.
  49. **
  50. **    演奏曲は、すべて CDDA_PLAY_no[] と そのポインタ CDDA_nplay によって管理して
  51. **    います. また、演奏開始時にはほとんどノーチェックなので、STOP時やエラー時にクリア作業
  52. **    をするようにしてます.
  53. **
  54. **    ステータス情報は、定期的に取得されることを大前提としています. CDDA_status() を
  55. **    呼ぶということ.
  56. -----------------------------------------------------------------------------*/
  57.  
  58. char    CDDA_FLG_libinit  = CDDA_FALSE ;    /*  初期化処理をしたか?        */
  59. char    CDDA_FLG_tocread  = CDDA_FALSE ;    /*  TOC情報を取得しているか?    */
  60. char    CDDA_FLG_pause    = CDDA_FALSE ;    /*  一時停止中か?                */
  61. char    CDDA_FLG_change   = CDDA_FALSE ;    /*  CDの入れ換えがあったか?    */
  62. char    CDDA_FLG_repeat   = CDDA_FALSE ;    /*  リピート演奏するのか?            */
  63. char    CDDA_FLG_pauseplay ;        /*  演奏開始指定時間にPAUSE解除するか?    */
  64. char    CDDA_FLG_shuffleinit ;        /*  シャッフル情報を初期化するのか?            */
  65. char    CDDA_FLG_nowplay ;                    /*  現在演奏中か?                */
  66. char    CDDA_FLG_cdstop ;                    /*  CDの回転を停止したか?        */
  67. char    CDDA_FLG_repeaton = CDDA_FALSE ;    /*  リピートを受け付けた?            */
  68. char    CDDA_FLG_stop     = CDDA_TRUE ;        /*  プログラム終了時にSTOPする?    */
  69. char    CDDA_FLG_stchange ;                    /*  ステータス変更ありか?            */
  70. char    CDDA_FLG_ffrew    = CDDA_FALSE ;    /*  FF/REW中か?                */
  71. char    CDDA_FLG_ffrewpause = CDDA_FALSE ;    /*  FF/REWのためにPAUSEしたか?    */
  72. char    CDDA_FLG_prgrepeat  = CDDA_FALSE ;    /*  プログラム演奏の最後の曲を削除
  73.                                                 後に再演奏をするのか?        */
  74.  
  75. int        CDDA_PLAY_no[CDDA_MAX_TRACK] ;        /*  演奏用曲番号格納            */
  76. int        CDDA_nplay ;                        /*  次は↑の内何番目か?        */
  77. int        CDDA_prgptr ;                        /*  プログラム用ポインタ                */
  78.  
  79. int        CDDA_PLAY_mode   = CDDA_SW_CONTINUE ;        /*  現在の演奏モード        */
  80.  
  81. /*****************************  演奏曲情報初期化  ****************************/
  82. void CDDA_music_clear( void )
  83. /*=============================================================================
  84. **    演奏曲の管理情報をクリアする.
  85. **
  86. **    < INPUT  > : なし
  87. **    < OUTPUT > : なし
  88. **    < RETURN > : なし
  89. =============================================================================*/
  90. {
  91.     int        c ;
  92.  
  93.     for ( c=0; c<CDDA_MAX_TRACK; c++ ) {
  94.         CDDA_PLAY_no[c] = CDDA_ZERO ;
  95.     }
  96.     CDDA_nplay  = CDDA_ZERO ;
  97.     CDDA_prgptr = CDDA_ZERO ;
  98.     CDDA_TOTAL_program  = CDDA_ZERO ;
  99.     CDDA_COUNT_program  = CDDA_ZERO ;
  100.     CDDA_REMAIN_program = CDDA_ZERO ;
  101.  
  102.     CDDA_TIME_program.min   = CDDA_ZERO ;
  103.     CDDA_TIME_program.sec   = CDDA_ZERO ;
  104.     CDDA_TIME_program.frame = CDDA_ZERO ;
  105.     memcpy( (char *)&CDDA_TIME_program2,(char *)&CDDA_TIME_music,
  106.             sizeof( CDDA_TRACK ) ) ;
  107.  
  108.     CDDA_FLG_prgrepeat  = CDDA_FALSE ;
  109. }
  110.  
  111. /******************************  各種情報初期化  *****************************/
  112. void CDDA_libinit( void )
  113. /*=============================================================================
  114. **    各種データの初期化を行う.
  115. **
  116. **    < INPUT  > : なし
  117. **    < OUTPUT > : なし
  118. **    < RETURN > : なし
  119. **
  120. **    当ライブラリ内では必ず最初にこの関数をCALLして下さい.
  121. =============================================================================*/
  122. {
  123.     static char    valflg = CDDA_FALSE ;
  124.     int        c ;
  125.  
  126.     if ( !valflg ) {
  127. /*    ↓↓                        ★★ DEBUG ★★                        ↓↓    */
  128.         if ( CDDA_DEBUG ) {
  129.             printf("\n<CDDA_libinit> CDDA Library start ...\n") ;
  130.         }
  131. /*    ↑↑                        ★★ DEBUG ★★                        ↑↑    */
  132.         CDDA_RANDINIT ;                            /*  乱数初期化                */
  133.         CDDA_INFO_buf.drv = 0 ;                    /*  FMTOWNS CDドライブ番号    */
  134.         valflg = CDDA_TRUE ;
  135.     }
  136.     CDDA_NOW_start       = CDDA_MIN_TRACK ;
  137.     CDDA_NOW_end         = CDDA_MAX_TRACK ;
  138.     CDDA_NOW_status      = CDDA_STAT_NOTREADY ;
  139.     CDDA_NOW_musicno     = CDDA_ZERO ;
  140.     CDDA_FLG_tocread     = CDDA_FALSE ;
  141.     CDDA_FLG_change      = CDDA_FALSE ;
  142.     CDDA_FLG_pause       = CDDA_FALSE ;
  143.     CDDA_FLG_pauseplay   = CDDA_FALSE ;
  144.     CDDA_FLG_shuffleinit = CDDA_TRUE ;
  145.     CDDA_FLG_nowplay     = CDDA_FALSE ;
  146.     CDDA_FLG_repeaton    = CDDA_FALSE ;
  147.     CDDA_FLG_cdstop      = CDDA_TRUE ;
  148.  
  149.     CDDA_INFO_buf.start  = CDDA_ZERO ;
  150.     CDDA_INFO_buf.end    = CDDA_ZERO ;
  151.  
  152.     CDDA_INFO_buf.discend.min   = CDDA_ZERO ;
  153.     CDDA_INFO_buf.discend.sec   = CDDA_ZERO ;
  154.     CDDA_INFO_buf.discend.frame = CDDA_ZERO ;
  155.  
  156.     CDDA_music_clear() ;                        /*  曲管理情報クリア            */
  157. /*-----------------------------------------------------------------------------
  158. **    シャッフルモードでは、CONTINUEモードに移行する.
  159. -----------------------------------------------------------------------------*/
  160.     if ( CDDA_PLAY_mode == CDDA_SW_SHUFFLE )
  161.         CDDA_PLAY_mode = CDDA_SW_CONTINUE ;
  162.  
  163.     for ( c=0; c<CDDA_MAX_TRACK; c++ ) {
  164.         memcpy( (char *)&CDDA_INFO_buf.track[c],(char *)&CDDA_INFO_buf.discend,
  165.                 sizeof( CDDA_TRACK ) ) ;
  166.         memcpy( (char *)&CDDA_TIME_track[c],(char *)&CDDA_INFO_buf.discend,
  167.                 sizeof( CDDA_TRACK ) ) ;
  168.     }
  169.     memcpy( (char *)&CDDA_TIME_music,(char *)&CDDA_INFO_buf.discend,
  170.             sizeof( CDDA_TRACK ) ) ;
  171.     memcpy( (char *)&CDDA_TIME_data,(char *)&CDDA_INFO_buf.discend,
  172.             sizeof( CDDA_TRACK ) ) ;
  173.     memcpy( (char *)&CDDA_CLOCK_nowtrack,(char *)&CDDA_INFO_buf.discend,
  174.             sizeof( CDDA_TRACK ) ) ;
  175.     memcpy( (char *)&CDDA_CLOCK_nowdisc,(char *)&CDDA_INFO_buf.discend,
  176.             sizeof( CDDA_TRACK ) ) ;
  177.     memcpy( (char *)&CDDA_TIME_nowtrack,(char *)&CDDA_INFO_buf.discend,
  178.             sizeof( CDDA_TRACK ) ) ;
  179.     memcpy( (char *)&CDDA_TIME_nowdisc,(char *)&CDDA_INFO_buf.discend,
  180.             sizeof( CDDA_TRACK ) ) ;
  181.     memcpy( (char *)&CDDA_CLOCK_program,(char *)&CDDA_INFO_buf.discend,
  182.             sizeof( CDDA_TRACK ) ) ;
  183.  
  184.     CDDA_FLG_libinit     = CDDA_TRUE ;
  185. }
  186.  
  187. /******************************  CD情報の取得  *****************************/
  188. int CDDA_cdinfo( void )
  189. /*=============================================================================
  190. **    CD情報取得命令を発行する.
  191. **
  192. **    < INPUT  > : なし
  193. **    < OUTPUT > : なし
  194. **    < RETURN > : エラー値
  195. **
  196. **    この関数にてCD情報を取得する際には、必ず数回のリトライを行って下さい.
  197. =============================================================================*/
  198. {
  199.     if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
  200.  
  201.     return(
  202.         cdr_cdinfo(
  203.             CDDA_INFO_buf.drv,&CDDA_INFO_buf.type,
  204.             &CDDA_INFO_buf.start,&CDDA_INFO_buf.end,
  205.             (char *)CDDA_INFO_buf.track,(char *)&CDDA_INFO_buf.discend
  206.         )
  207.     ) ;
  208. }
  209.  
  210. /****************************  TOC情報の取得  *****************************/
  211. int CDDA_tocread( void )
  212. /*=============================================================================
  213. **    TOC情報を取得する.
  214. **
  215. **    < INPUT  > : なし
  216. **    < OUTPUT > : なし
  217. **    < RETURN > : = 偽 - TOC 読み込み成功(エラーなし)
  218. **                   真 - TOC 読み込み失敗(エラーあり)
  219. =============================================================================*/
  220. {
  221.     int        errcnt, ret ;
  222.     int        c ;
  223.  
  224. /*
  225. **    共通フラグの初期化
  226. */
  227.     CDDA_libinit() ;
  228.  
  229. /*
  230. **    CD 回転停止時間を連続回転に設定
  231. */
  232.     cdr_pause( CDDA_INFO_buf.drv ) ;
  233.     cdr_stptime( CDDA_INFO_buf.drv,CDDA_ZERO ) ;
  234.  
  235. /*
  236. **    TOC 読み込み
  237. */
  238. /*-----------------------------------------------------------------------------
  239. **    TOC 取得時には、CD の回転が安定するまでの間 エラー となるので、必ず リトライ
  240. **    処理をする必要がある.
  241. -----------------------------------------------------------------------------*/
  242.     errcnt = CDDA_ZERO ;
  243.     do {
  244.         ret = CDDA_cdinfo() ;
  245.         cdr_pause( CDDA_INFO_buf.drv ) ;
  246.         errcnt++ ;
  247.     } while ( ret && errcnt<=CDDA_RETRY ) ;
  248.  
  249.     if ( errcnt > CDDA_RETRY ) {                    /*  TOC 読み込み失敗!    */
  250.         CDDA_libinit() ;
  251.  
  252. /*    ↓↓                        ★★ DEBUG ★★                        ↓↓    */
  253.         if ( CDDA_DEBUG ) {
  254.             printf("\n<CDDA_tocread> TOC read NG!!!\n") ;
  255.         }
  256. /*    ↑↑                        ★★ DEBUG ★★                        ↑↑    */
  257.  
  258.         return( CDDA_ERR_NOTREADY ) ;
  259.  
  260.     } else {                                        /*  TOC 読み込み成功♪    */
  261.         CDDA_FLG_tocread = CDDA_TRUE ;
  262.         CDDA_NOW_status  = CDDA_STAT_STOP ;
  263.  
  264. /*-----------------------------------------------------------------------------
  265. **        各曲の演奏時間および データ部分,音楽部分の合計時間を求める.
  266. -----------------------------------------------------------------------------*/
  267.         CDDA_timecalc() ;
  268.         memcpy( (char *)&CDDA_TIME_program2,(char *)&CDDA_TIME_music,
  269.                 sizeof( CDDA_TRACK ) ) ;
  270.  
  271. /*-----------------------------------------------------------------------------
  272. **    演奏曲の番号を保持する.
  273. **    シャッフルモードでは、CONTINUEモードに移行する.
  274. **    プログラムモード については、演奏曲を クリア しておく.
  275. -----------------------------------------------------------------------------*/
  276.         switch ( CDDA_PLAY_mode ) {
  277.         case CDDA_SW_SHUFFLE :
  278.             CDDA_PLAY_mode = CDDA_SW_CONTINUE ;
  279.         case CDDA_SW_CONTINUE :
  280.         case CDDA_SW_SINGLE :
  281.             for ( c=0; c<CDDA_INFO_buf.end; c++ )
  282.                 CDDA_PLAY_no[c] = c+1 ;
  283.             break ;
  284.         case CDDA_SW_PROGRAM :
  285.             break ;
  286.         }
  287.  
  288. /*    ↓↓                        ★★ DEBUG ★★                        ↓↓    */
  289.         if ( CDDA_DEBUG ) {
  290.             printf( "\n<CDDA_tocread> TOC read OK!\n" ) ;
  291.             for ( c=0; c<CDDA_INFO_buf.end; c++ ) {
  292.                 printf( "%02d : %2d-%02d-%02d ; ",c+1,CDDA_TIME_track[c].min,
  293.                     CDDA_TIME_track[c].sec,CDDA_TIME_track[c].frame ) ;
  294.                 if ( CDDA_data_check( c+1 ) ) printf( "データ\n" ) ;
  295.                 else printf( "音楽\n" ) ;
  296.             }
  297.             printf( "\n" ) ;
  298.         }
  299. /*    ↑↑                        ★★ DEBUG ★★                        ↑↑    */
  300.  
  301.         return( CDDA_ERR_NOERROR ) ;
  302.     }
  303. }
  304.  
  305. /*********************************  CDシーク  *********************************/
  306. int CDDA_seek( void )
  307. /*=============================================================================
  308. **    CD の ヘッド を演奏開始位置に移動する.
  309. **
  310. **    < INPUT  > : なし
  311. **    < OUTPUT > : なし
  312. **    < RETURN > : エラー値
  313. **
  314. **    CDDA_CLOCK_start を設定してからこの関数をCALLすること.
  315. =============================================================================*/
  316. {
  317.     if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
  318.  
  319. /*
  320. **    CDDA のないコンパクトディスクには用がない!
  321. */
  322.     if ( CDDA_INFO_buf.type != CDDA_TYPE_CDDA &&
  323.             CDDA_INFO_buf.type != CDDA_TYPE_BOTH ) return( CDDA_ERR_NOMUSIC ) ;
  324.  
  325.     if ( CDDA_NOW_status == CDDA_STAT_NOTREADY ) return( CDDA_ERR_NOTREADY ) ;
  326.     if ( CDDA_NOW_status == CDDA_STAT_PLAY ) return( CDDA_ERR_NOWPLAY ) ;
  327.  
  328.     return(
  329.         cdr_tseek( CDDA_INFO_buf.drv,(char *)&CDDA_CLOCK_start )
  330.     ) ;
  331. }
  332.  
  333. /*******************************  CD演奏  **********************************/
  334. int CDDA_mtrplay( void )
  335. /*=============================================================================
  336. **    CD演奏命令を発行する.
  337. **
  338. **    < INPUT  > : なし
  339. **    < OUTPUT > : なし
  340. **    < RETURN > : エラー値
  341. **
  342. **    CDDA_CLOCK_start および CDDA_CLOCK_end を設定してからこの関数をCALLする
  343. **    こと.
  344. =============================================================================*/
  345. {
  346.     int        rep, st ;
  347.  
  348.     if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
  349.  
  350. /*
  351. **    CDDA のないコンパクトディスクには用がない!
  352. */
  353.     if ( CDDA_INFO_buf.type != CDDA_TYPE_CDDA &&
  354.             CDDA_INFO_buf.type != CDDA_TYPE_BOTH ) return( CDDA_ERR_NOMUSIC ) ;
  355.  
  356. /*-----------------------------------------------------------------------------
  357. **    CONTINUEモードで最初から最後までをリピートありで演奏する時だけ、繰り返し演奏
  358. **    命令を発行する. それ以外は、一回だけの演奏とする.
  359. **
  360. **    各演奏モードは、演奏終了したかどうかのチェックなどを行う時に、繰り返し演奏さ
  361. **    れていないことを前提としている.
  362. -----------------------------------------------------------------------------*/
  363.     rep = CDDA_MIN_REPEAT ;
  364.     st  = CDDA_INFO_buf.start ;
  365.     if ( CDDA_INFO_buf.type == CDDA_TYPE_BOTH ) st ++ ;
  366.     if ( CDDA_FLG_repeaton && CDDA_PLAY_mode == CDDA_SW_CONTINUE &&
  367.             CDDA_NOW_start == st && CDDA_NOW_end == CDDA_INFO_buf.end &&
  368.             !CDDA_data_check( st ) ) {
  369.         rep = CDDA_MAX_REPEAT ;
  370.     }
  371.  
  372.     return(
  373.         cdr_mtrplay(
  374.             CDDA_INFO_buf.drv,
  375.             (char *)&CDDA_CLOCK_start,(char *)&CDDA_CLOCK_end,rep
  376.         )
  377.     ) ;
  378. }
  379.  
  380. /*************************  CDの演奏を停止します。 *************************/
  381. void CDDA_stop( void )
  382. /*=============================================================================
  383. **    CD演奏停止命令を発行する.
  384. **
  385. **    < INPUT  > : なし
  386. **    < OUTPUT > : なし
  387. **    < RETURN > : なし
  388. =============================================================================*/
  389. {
  390.     int        errcnt, ret ;
  391.  
  392.     if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
  393.  
  394. /*-----------------------------------------------------------------------------
  395. **    CD が入れ換えられた後に初めて アクセス した時のことを考えて、停止処理も リトライ
  396. **    処理を行う.
  397. -----------------------------------------------------------------------------*/
  398.     errcnt = CDDA_ZERO ;
  399.     do {
  400.         ret = cdr_mstop( CDDA_INFO_buf.drv ) ;
  401.         errcnt++ ;
  402.     } while ( ret && errcnt<=CDDA_RETRY ) ;
  403.  
  404. /*-----------------------------------------------------------------------------
  405. **    制御フラグクリア
  406. -----------------------------------------------------------------------------*/
  407.     CDDA_NOW_status      = CDDA_STAT_STOP ;
  408.     CDDA_NOW_musicno     = CDDA_ZERO ;
  409.     CDDA_NOW_pause       = CDDA_ZERO ;
  410.     CDDA_FLG_pause       = CDDA_FALSE ;
  411.     CDDA_FLG_pauseplay   = CDDA_FALSE ;
  412.     CDDA_FLG_shuffleinit = CDDA_TRUE ;
  413.     CDDA_FLG_cdstop      = CDDA_TRUE ;
  414.     CDDA_FLG_repeaton    = CDDA_FALSE ;
  415.  
  416. /*-----------------------------------------------------------------------------
  417. **    プログラムモード時には、演奏曲を示すポインタをクリアしてしまうと、いったんSTOPして
  418. **    途中からPLAYした時にプログラム設定された最初の曲(既に演奏終了したものを含)
  419. **    から演奏してしまうことになる.
  420. **
  421. **    プログラムモード時のポインタクリアは、STOPキー(本ライブラリに対してSTOP命令を発行する)の
  422. **    指定があった時に行う.
  423. -----------------------------------------------------------------------------*/
  424.     if ( CDDA_PLAY_mode != CDDA_SW_PROGRAM ) {
  425.         CDDA_nplay       = CDDA_ZERO ;
  426.         CDDA_prgptr      = CDDA_ZERO ;
  427.     }
  428. }
  429.  
  430. /***************************  CD演奏状態の取得  ****************************/
  431. int CDDA_mphase( void )
  432. /*=============================================================================
  433. **    CD演奏状態取得命令を発行する.
  434. **
  435. **    < INPUT  > : なし
  436. **    < OUTPUT > : なし
  437. **    < RETURN > : エラー値
  438. =============================================================================*/
  439. {
  440.     if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
  441.  
  442.     return(
  443.         cdr_mphase(
  444.             CDDA_INFO_buf.drv,&CDDA_NOW_status,&CDDA_NOW_musicno,
  445.             (char *)&CDDA_CLOCK_nowtrack,(char *)&CDDA_CLOCK_nowdisc
  446.         )
  447.     ) ;
  448. }
  449.  
  450. /****************************  シャッフル演奏状態を監視  **************************/
  451. int CDDA_shuffle_check( void )
  452. /*=============================================================================
  453. **    シャッフル演奏状態のチェックを行う.
  454. **
  455. **    < INPUT  > : なし
  456. **    < OUTPUT > : なし
  457. **    < RETURN > : エラー値
  458. **
  459. **    この関数は、演奏状態を取得後CALLして下さい.
  460. =============================================================================*/
  461. {
  462.     int        ret ;
  463.  
  464.     ret = CDDA_ERR_NOERROR ;
  465.     switch ( CDDA_NOW_status ) {
  466.     case CDDA_STAT_STOP :
  467. /*-----------------------------------------------------------------------------
  468. **    シャッフルモードでは、全ての曲を終了するまでは STOP 状態ということはない.
  469. **    STOP状態ならば、シャッフル時の次の曲を調べて演奏をする.
  470. -----------------------------------------------------------------------------*/
  471.         if ( CDDA_FLG_nowplay ) {
  472.             ret = CDDA_shuffle( &CDDA_NOW_start ) ;
  473.             if ( !ret ) {
  474.                 CDDA_NOW_end = CDDA_NOW_start ;
  475.                 CDDA_FLG_stchange = CDDA_TRUE ;
  476.                 ret = CDDA_play() ;
  477.             } else {
  478. /*-----------------------------------------------------------------------------
  479. **    シャッフルモード時に全ての曲を演奏終了していても、リピート指定があった時には再度
  480. **    シャッフル演奏を行う.
  481. -----------------------------------------------------------------------------*/
  482.                 if ( CDDA_FLG_repeaton ) {
  483. /*-----------------------------------------------------------------------------
  484. **    シャッフルをし直すには、CDDA_FLG_shuffleinit を 真値 にして CDDA_shuffle()
  485. **    を CALL する.
  486. -----------------------------------------------------------------------------*/
  487.                     CDDA_FLG_shuffleinit = CDDA_TRUE ;
  488.                     if ( !CDDA_shuffle( &CDDA_NOW_start ) ) {
  489.                         CDDA_NOW_end = CDDA_NOW_start ;
  490.                         CDDA_FLG_stchange = CDDA_TRUE ;
  491.                         ret = CDDA_play() ;
  492.                         if ( !ret ) ret = CDDA_ERR_REPEAT ;
  493.                     } else {
  494. /*-----------------------------------------------------------------------------
  495. **    シャッフルをし直しても次の曲番号がない時には、音楽のない CD だと判断する.
  496. -----------------------------------------------------------------------------*/
  497.                         ret = CDDA_ERR_NOMUSIC ;
  498.                     }
  499.                 } else {
  500. /*-----------------------------------------------------------------------------
  501. **    演奏終了 : CD の回転を停止させるため STOP する.
  502. -----------------------------------------------------------------------------*/
  503.                     if ( !CDDA_FLG_cdstop ) CDDA_stop() ;
  504.                     CDDA_FLG_nowplay = CDDA_FALSE ;
  505.                     ret = CDDA_ERR_NOERROR ;
  506.                 }
  507.             }
  508.  
  509.         } else {
  510. /*-----------------------------------------------------------------------------
  511. **    演奏終了 : CD の回転を停止させるため STOP する.
  512. -----------------------------------------------------------------------------*/
  513.             if ( !CDDA_FLG_cdstop ) CDDA_stop() ;
  514.             CDDA_FLG_nowplay = CDDA_FALSE ;
  515.         }
  516.         break ;
  517.     case CDDA_STAT_PLAY :
  518. /*-----------------------------------------------------------------------------
  519. **    シャッフル演奏時は、シングルと同じく一曲演奏なので、演奏開始曲と現在の演奏曲が
  520. **    異なることはない.
  521. **    異なった時には、演奏指定した次の曲に突入しているので、シャッフル用の次の曲
  522. **    を演奏する.
  523. -----------------------------------------------------------------------------*/
  524.         if ( CDDA_NOW_musicno != CDDA_NOW_start ) {
  525.             ret = CDDA_shuffle( &CDDA_NOW_start ) ;
  526.             if ( !ret ) {
  527.                 CDDA_NOW_end = CDDA_NOW_start ;
  528.                 CDDA_FLG_stchange = CDDA_TRUE ;
  529.                 ret = CDDA_play() ;
  530.             } else {
  531. /*-----------------------------------------------------------------------------
  532. **    シャッフル用の次の曲がない時には、全ての曲の演奏を終了した時であるので、演奏
  533. **    を停止する(リピート指定のない時).
  534. -----------------------------------------------------------------------------*/
  535.                 if ( CDDA_FLG_repeaton ) {
  536. /*-----------------------------------------------------------------------------
  537. **    シャッフルをし直すには、CDDA_FLG_shuffleinit を 真値 にして CDDA_shuffle()
  538. **    を CALL する.
  539. -----------------------------------------------------------------------------*/
  540.                     CDDA_FLG_shuffleinit = CDDA_TRUE ;
  541.                     if ( !CDDA_shuffle( &CDDA_NOW_start ) ) {
  542.                         CDDA_NOW_end = CDDA_NOW_start ;
  543.                         CDDA_FLG_stchange = CDDA_TRUE ;
  544.                         ret = CDDA_play() ;
  545.                         if ( !ret ) ret = CDDA_ERR_REPEAT ;
  546.                     } else {
  547. /*-----------------------------------------------------------------------------
  548. **    シャッフルをし直しても次の曲番号がない時には、音楽のない CD だと判断する.
  549. -----------------------------------------------------------------------------*/
  550.                         ret = CDDA_ERR_NOMUSIC ;
  551.                     }
  552.                 } else {
  553.                     CDDA_FLG_stchange = CDDA_TRUE ;
  554.                     CDDA_stop() ;
  555.                     CDDA_FLG_nowplay = CDDA_FALSE ;
  556.                     ret = CDDA_ERR_NOERROR ;
  557.                 }
  558.             }
  559.         }
  560.         break ;
  561.     }
  562.  
  563.     return( ret ) ;
  564. }
  565.  
  566. /***************************  プログラム演奏状態を監視  *************************/
  567. void CDDA_program_playend( void )
  568. /*=============================================================================
  569. **    プログラム演奏の終了.
  570. **
  571. **    < INPUT  > : なし
  572. **    < OUTPUT > : なし
  573. **    < RETURN > : なし
  574. **
  575. **    この関数は、CDDA_program_check() から呼ばれる.
  576. =============================================================================*/
  577. {
  578.     if ( CDDA_NOW_status != CDDA_STAT_STOP ) CDDA_FLG_stchange = CDDA_TRUE ;
  579.     if ( !CDDA_FLG_cdstop ) {
  580.         CDDA_stop() ;
  581.         CDDA_music_clear() ;                    /*  曲管理情報クリア            */
  582.     }
  583.     CDDA_FLG_nowplay = CDDA_FALSE ;
  584. }
  585.  
  586. /***************************  プログラム演奏状態を監視  *************************/
  587. int CDDA_program_check( void )
  588. /*=============================================================================
  589. **    プログラム演奏状態のチェックを行う.
  590. **
  591. **    < INPUT  > : なし
  592. **    < OUTPUT > : なし
  593. **    < RETURN > : エラー値
  594. **
  595. **    この関数は、演奏状態を取得後CALLして下さい.
  596. =============================================================================*/
  597. {
  598.     int        ret ;
  599.     int        no ;
  600.  
  601.     ret = CDDA_ERR_NOERROR ;
  602.     switch ( CDDA_NOW_status ) {
  603.     case CDDA_STAT_STOP :
  604.     case CDDA_STAT_PAUSE :
  605. /*-----------------------------------------------------------------------------
  606. **    プログラムモードには、演奏曲を全て演奏していないのに停止している時がある.
  607. **    (曲番号指定時とか確認時など)
  608. **
  609. **    そのために、利用者が STOP 状態としているのならば、次の曲を処理しないよう
  610. **    にする. そのために CDDA_FLG_nowplay が 真値 か 偽値 かどうかで判断する.
  611. **
  612. **    CDDA_FLG_nowplay は、演奏指示があった時に 真値とし、演奏中に STOP した
  613. **    時または演奏指示が出ていない時には、偽値とする. この フラグ 操作は、キー
  614. **    入力時(本ライブラリに対しスイッチ指定ありの時)とする.
  615. **
  616. **    プログラム登録曲の最後の曲がPAUSE中に削除された時には、リピートなしならば停止
  617. **    処理をし、リピートありならば演奏開始時間の設定だけを行っておく.
  618. **    CDDA_program_data_clear()にて、演奏中の曲を削除した時に リピート 演奏に入っ
  619. **    たことを知らせるために、ここでその処理を行う.
  620. -----------------------------------------------------------------------------*/
  621.         if ( CDDA_NOW_status == CDDA_STAT_PAUSE && !CDDA_FLG_prgrepeat )
  622.             return( ret ) ;
  623.  
  624.         if ( CDDA_FLG_nowplay || CDDA_FLG_prgrepeat ) {
  625.  
  626.             if ( CDDA_FLG_prgrepeat ) {
  627.                 CDDA_nplay = CDDA_ZERO ;
  628.                 if ( CDDA_NOW_status == CDDA_STAT_PAUSE ) {
  629.                     if ( !CDDA_ffmusic() ) {
  630.                         CDDA_FLG_stchange = CDDA_TRUE ;
  631.                         CDDA_REMAIN_program = CDDA_TOTAL_program ;
  632.                         ret = CDDA_ERR_REPEAT ;
  633.                     } else {
  634.                         CDDA_program_playend() ;
  635.                     }
  636.                 } else {
  637.                     if ( !CDDA_next_music() ) {
  638.                         CDDA_FLG_stchange = CDDA_TRUE ;
  639.                         CDDA_REMAIN_program = CDDA_TOTAL_program ;
  640.                         ret = CDDA_play() ;
  641.                         if ( !ret ) ret = CDDA_ERR_REPEAT ;
  642.                     } else {
  643.                         CDDA_program_playend() ;
  644.                     }
  645.                 }
  646.                 CDDA_FLG_prgrepeat = CDDA_FALSE ;
  647.  
  648.             } else if ( !CDDA_next_music() ) {
  649.                 CDDA_FLG_stchange = CDDA_TRUE ;
  650.                 ret = CDDA_play() ;
  651.             } else {
  652. /*-----------------------------------------------------------------------------
  653. **    次の曲がなければ、リピート指定ありかどうかチェックし、リピート指定ありならば、プロ
  654. **    グラム指定された最初の曲から演奏する. (リプレイ)
  655. -----------------------------------------------------------------------------*/
  656.                 if ( CDDA_FLG_repeaton ) {
  657.                     CDDA_nplay = CDDA_ZERO ;
  658.                     if ( !CDDA_next_music() ) {
  659.                         CDDA_FLG_stchange = CDDA_TRUE ;
  660.                         CDDA_REMAIN_program = CDDA_TOTAL_program ;
  661.                         ret = CDDA_play() ;
  662.                         if ( !ret ) ret = CDDA_ERR_REPEAT ;
  663.                     } else {
  664. /*-----------------------------------------------------------------------------
  665. **    次の曲(最初の曲)がない時には、演奏終了.
  666. -----------------------------------------------------------------------------*/
  667.                         CDDA_program_playend() ;
  668.                     }
  669.                 } else {
  670. /*-----------------------------------------------------------------------------
  671. **    演奏終了 : CD の回転を停止させるため STOP する.
  672. **    何もしないで、演奏が終了したならば、プログラム曲を全て クリア する.
  673. -----------------------------------------------------------------------------*/
  674.                     CDDA_program_playend() ;
  675.                 }
  676.             }
  677.         } else {
  678. /*-----------------------------------------------------------------------------
  679. **    演奏終了 : CD の回転を停止させるため STOP する.
  680. -----------------------------------------------------------------------------*/
  681.             CDDA_program_playend() ;
  682.         }
  683.         break ;
  684.     case CDDA_STAT_PLAY :
  685. /*-----------------------------------------------------------------------------
  686. **    プログラムモード時は、シングルと同じく一曲演奏なので、今演奏中の曲と演奏中で
  687. **    あるべき曲とが異なることはない. その時には、演奏指定した次の曲に突入
  688. **    しているので、プログラム指定された次の曲を演奏する.
  689. **    ただし、CDDA_NOW_musicno が 0 以下の時は プログラム曲確認中などにあり得る
  690. **    ので、その場合は チェック からはずす.
  691. **
  692. **    演奏中であるべきの曲は、CDDA_PLAY_no[] とその ポインタ CDDA_nplay により
  693. **    求める.
  694. -----------------------------------------------------------------------------*/
  695.         if ( CDDA_NOW_musicno <= CDDA_ZERO ) break ;
  696.         if ( CDDA_nplay > CDDA_ZERO ) {
  697.             no = CDDA_PLAY_no[CDDA_nplay-1] ;
  698.         } else {
  699.             no = CDDA_PLAY_no[CDDA_ZERO] ;
  700.         }
  701. /*-----------------------------------------------------------------------------
  702. **    演奏中であるべき曲の次の曲を演奏していた時は、次のプログラム曲を演奏する.
  703. -----------------------------------------------------------------------------*/
  704.         if ( CDDA_NOW_musicno == (no+1) ) {
  705.             if ( !CDDA_next_music() ) {
  706.                 CDDA_FLG_stchange = CDDA_TRUE ;
  707.                 ret = CDDA_play() ;
  708.             } else {
  709. /*-----------------------------------------------------------------------------
  710. **    プログラム指定された次の曲がない時には、全ての曲の演奏を終了した時であるの
  711. **    で、演奏を停止する(リピート指定のない時).
  712. -----------------------------------------------------------------------------*/
  713.                 if ( CDDA_FLG_repeaton ) {
  714.                     CDDA_nplay = CDDA_ZERO ;
  715.                     if ( !CDDA_next_music() ) {
  716.                         CDDA_FLG_stchange = CDDA_TRUE ;
  717.                         CDDA_REMAIN_program = CDDA_TOTAL_program ;
  718.                         ret = CDDA_play() ;
  719.                         if ( !ret ) ret = CDDA_ERR_REPEAT ;
  720.                     } else {
  721. /*-----------------------------------------------------------------------------
  722. **    次の曲(最初の曲)がない時には、演奏終了.
  723. -----------------------------------------------------------------------------*/
  724.                         CDDA_FLG_stchange = CDDA_TRUE ;
  725.                         CDDA_program_playend() ;
  726.                     }
  727.                 } else {
  728. /*-----------------------------------------------------------------------------
  729. **    停止時には、全ての曲を終了したことにするために フラグ と ポインタ を クリア する.
  730. -----------------------------------------------------------------------------*/
  731.                     CDDA_program_playend() ;
  732.                 }
  733.             }
  734.         }
  735.         break ;
  736.     }
  737.  
  738.     return( ret ) ;
  739. }
  740.  
  741. /****************************  全曲演奏状態を監視  ***************************/
  742. int CDDA_continue_check( int musicno )
  743. /*=============================================================================
  744. **    全曲演奏モード時の演奏状態のチェックを行う.
  745. **
  746. **    < INPUT  > : なし
  747. **    < OUTPUT > : なし
  748. **    < RETURN > : エラー値
  749. **
  750. **    この関数は、演奏状態を取得後CALLして下さい.
  751. =============================================================================*/
  752. {
  753.     int        ret ;
  754.     int        st ;
  755.  
  756.     ret = CDDA_ERR_NOERROR ;
  757.     switch ( CDDA_NOW_status ) {
  758.     case CDDA_STAT_STOP :
  759.         if ( CDDA_NOW_end < CDDA_INFO_buf.end && CDDA_FLG_nowplay ) {
  760. /*-----------------------------------------------------------------------------
  761. **    CONTINUEモード時は、最後の曲まで演奏していないのに停止していることはない.
  762. **    その時は、他のモードから移行してきた時であるので、最終曲まで演奏しているか
  763. **    どうかで判断し、終了した曲の次の曲から最後の曲までを演奏する.
  764. -----------------------------------------------------------------------------*/
  765.             CDDA_NOW_start = CDDA_NOW_end + 1 ;
  766.             CDDA_NOW_end   = CDDA_INFO_buf.end ;
  767.             CDDA_nplay     = CDDA_NOW_start ;
  768.             CDDA_FLG_stchange = CDDA_TRUE ;
  769.             ret = CDDA_play() ;
  770.         } else {
  771.             if ( CDDA_FLG_repeaton ) {
  772. /*-----------------------------------------------------------------------------
  773. **    リピート指定されていて最後の曲まで演奏し終わって、停止していた時には、最初
  774. **    から最後の曲までを演奏する.
  775. -----------------------------------------------------------------------------*/
  776.                 CDDA_nplay     = CDDA_ZERO ;
  777.                 CDDA_NOW_start = CDDA_INFO_buf.start ;
  778.                 CDDA_NOW_end   = CDDA_INFO_buf.end ;
  779.                 CDDA_FLG_stchange = CDDA_TRUE ;
  780.                 ret = CDDA_play() ;
  781.                 if ( !ret ) ret = CDDA_ERR_REPEAT ;
  782.             } else {
  783. /*-----------------------------------------------------------------------------
  784. **    演奏終了 : CD の回転を停止させるため STOP する.
  785. -----------------------------------------------------------------------------*/
  786.                 if ( !CDDA_FLG_cdstop ) CDDA_stop() ;
  787.                 CDDA_FLG_nowplay = CDDA_FALSE ;
  788.             }
  789.         }
  790.         break ;
  791.     case CDDA_STAT_PLAY :
  792.         if ( musicno != CDDA_NOW_musicno && musicno ) {
  793. /*-----------------------------------------------------------------------------
  794. **    演奏曲が変わった時に、その曲が音楽であるかどうかを チェック する.
  795. **    音楽でなく データ である場合には、その次の曲(音楽)から演奏をする.
  796. **    また、指定されていた終了曲よりもあとの曲になった場合も同様である.
  797. **    (惰性で次の曲に突入してしまった場合のこと)
  798. -----------------------------------------------------------------------------*/
  799.             if ( CDDA_NOW_musicno <= CDDA_ZERO ) break ;
  800.             if ( CDDA_NOW_musicno > CDDA_NOW_end ) {
  801. /*-----------------------------------------------------------------------------
  802. **    CDDA_NOW_musicno が行き過ぎた曲の時に、ステータス取得時に演奏中であれば、演奏
  803. **    ポインタ が行き過ぎた曲に合わせられてしまう. そこで正しい位置に ポインタ を
  804. **    設定し直す.
  805. -----------------------------------------------------------------------------*/
  806.                 CDDA_nplay = musicno ;
  807.             }
  808.             if ( CDDA_data_check( CDDA_NOW_musicno ) ||    /*  データ            */
  809.                     CDDA_NOW_musicno > CDDA_NOW_end ) {    /*  次の曲に突入    */
  810.                 CDDA_FLG_stchange = CDDA_TRUE ;
  811.                 if ( !CDDA_next_music() ) {
  812.                     ret = CDDA_play() ;
  813.                 } else {
  814.                     if ( CDDA_FLG_repeaton ) {
  815. /*-----------------------------------------------------------------------------
  816. **    リピート指定されていて最後の曲まで演奏し終わって、停止していた時には、最初
  817. **    から最後の曲までを演奏する.
  818. -----------------------------------------------------------------------------*/
  819.                         CDDA_nplay     = CDDA_ZERO ;
  820.                         CDDA_NOW_start = CDDA_INFO_buf.start ;
  821.                         CDDA_NOW_end   = CDDA_INFO_buf.end ;
  822.                         ret = CDDA_play() ;
  823.                         if ( !ret ) ret = CDDA_ERR_REPEAT ;
  824.                     } else {
  825.                         CDDA_stop() ;
  826.                         CDDA_FLG_nowplay = CDDA_FALSE ;
  827.                         ret = CDDA_ERR_NOERROR ;
  828.                     }
  829.                 }
  830.             }
  831. /*-----------------------------------------------------------------------------
  832. **    繰り返し演奏時のチェックをする.
  833. -----------------------------------------------------------------------------*/
  834.             st  = CDDA_INFO_buf.start ;
  835.             if ( CDDA_INFO_buf.type == CDDA_TYPE_BOTH ) st ++ ;
  836.             if ( CDDA_FLG_repeaton && CDDA_NOW_start == st &&
  837.                     CDDA_NOW_end == CDDA_INFO_buf.end &&
  838.                     !CDDA_data_check( st ) ) {
  839.                 if ( musicno == CDDA_NOW_end && CDDA_NOW_musicno == st )
  840.                     ret = CDDA_ERR_REPEAT ;
  841.             }
  842.         }
  843.         break ;
  844.     }
  845.  
  846.     return( ret ) ;
  847. }
  848.  
  849. /****************************  一曲演奏状態を監視  ***************************/
  850. int CDDA_single_check( int mode )
  851. /*=============================================================================
  852. **    一曲演奏モード時の演奏状態のチェックを行う.
  853. **
  854. **    < INPUT  > : 前回の演奏モード
  855. **    < OUTPUT > : なし
  856. **    < RETURN > : エラー値
  857. **
  858. **    この関数は、演奏状態を取得後CALLして下さい.
  859. =============================================================================*/
  860. {
  861.     int        ret ;
  862.  
  863.     ret = CDDA_ERR_NOERROR ;
  864.     switch ( CDDA_NOW_status ) {
  865.     case CDDA_STAT_STOP :
  866. /*-----------------------------------------------------------------------------
  867. **    シングルモード時は、リピート指定がない限り停止していても良い.
  868. **    リピート指定がある時には、再度演奏を開始する.
  869. **
  870. **    ここでは、次の曲/前の曲という指定の仕方ではないため、ポインタ をここで設定
  871. **    しておく必要がある. 
  872. -----------------------------------------------------------------------------*/
  873.         if ( CDDA_FLG_repeaton ) {
  874.             CDDA_NOW_end = CDDA_NOW_start ;
  875.             CDDA_nplay   = CDDA_NOW_start ;
  876.             CDDA_FLG_stchange = CDDA_TRUE ;
  877.             ret = CDDA_play() ;
  878.             if ( !ret ) ret = CDDA_ERR_REPEAT ;
  879.         } else {
  880. /*-----------------------------------------------------------------------------
  881. **    演奏終了 : CD の回転を停止させるため STOP する.
  882. -----------------------------------------------------------------------------*/
  883.             if ( !CDDA_FLG_cdstop ) CDDA_stop() ;
  884.             CDDA_FLG_nowplay = CDDA_FALSE ;
  885.         }
  886.         break ;
  887.     case CDDA_STAT_PLAY :
  888. /*-----------------------------------------------------------------------------
  889. **    シングルモード時に、演奏開始曲と現在の曲が異なることはない.
  890. **    異なっている時には、演奏指定した曲の次の曲に突入しているので、演奏を停止
  891. **    する. ただし、リピート指定ありの時には、再度演奏指定されていた曲を演奏する.
  892. -----------------------------------------------------------------------------*/
  893.         if ( mode == CDDA_PLAY_mode &&
  894.                 CDDA_NOW_start != CDDA_NOW_musicno ) {
  895.             CDDA_FLG_stchange = CDDA_TRUE ;
  896.             if ( CDDA_FLG_repeaton ) {
  897.                 CDDA_NOW_end = CDDA_NOW_start ;
  898.                 CDDA_nplay   = CDDA_NOW_start ;
  899.                 ret = CDDA_play() ;
  900.                 if ( !ret ) ret = CDDA_ERR_REPEAT ;
  901.             } else {
  902.                 CDDA_stop() ;
  903.                 CDDA_FLG_nowplay = CDDA_FALSE ;
  904.                 ret = CDDA_ERR_NOERROR ;
  905.             }
  906.         }
  907.         break ;
  908.     }
  909.  
  910.     return( ret ) ;
  911. }
  912.  
  913. /************************  CDの現在の演奏状態を監視  ***********************/
  914. int CDDA_play_check( void )
  915. /*=============================================================================
  916. **    演奏状態のチェックを行う.
  917. **
  918. **    < INPUT  > : なし
  919. **    < OUTPUT > : なし
  920. **    < RETURN > : エラー値
  921. **
  922. **    この関数は、演奏状態を取得後CALLして下さい.
  923. **
  924. **    この関数は、毎秒2~3回CALLするようにして下さい. そうしないと、演奏モード
  925. **    のとおりに演奏されません. また、演奏時間も保証されません.
  926. =============================================================================*/
  927. {
  928.     static int    mode    = CDDA_SW_CONTINUE ;
  929.     static int    musicno = CDDA_ZERO ;
  930.     int        ret ;
  931.  
  932.     ret = CDDA_ERR_NOERROR ;
  933. /*-----------------------------------------------------------------------------
  934. **    各演奏モード毎に、今の演奏状態が妥当であるかどうかを チェック し、然るべき処理
  935. **    をとる.
  936. -----------------------------------------------------------------------------*/
  937.     switch ( CDDA_PLAY_mode ) {
  938.     case CDDA_SW_SHUFFLE :
  939.         ret = CDDA_shuffle_check() ;
  940.         break ;
  941.     case CDDA_SW_PROGRAM :
  942.         ret = CDDA_program_check() ;
  943.         break ;
  944.     case CDDA_SW_CONTINUE :
  945.         ret = CDDA_continue_check( musicno ) ;
  946.         break ;
  947.     case CDDA_SW_SINGLE :
  948.         ret = CDDA_single_check( mode ) ;
  949.         break ;
  950.     }
  951.  
  952. /*-----------------------------------------------------------------------------
  953. **    前回の演奏曲と演奏モードを保持しておく.
  954. -----------------------------------------------------------------------------*/
  955.     mode    = CDDA_PLAY_mode ;
  956.     musicno = CDDA_NOW_musicno ;
  957.  
  958.     return( ret ) ;
  959. }
  960.  
  961. /************************  CDの現在の演奏ポインタのチェック  **********************/
  962. void CDDA_nplay_check( void )
  963. /*=============================================================================
  964. **    演奏曲格納領域のポインタのチェックを行う.
  965. **
  966. **    < INPUT  > : なし
  967. **    < OUTPUT > : なし
  968. **    < RETURN > : なし
  969. **
  970. **    この関数は、演奏状態を取得後CALLして下さい.
  971. =============================================================================*/
  972. {
  973.     int        c ;
  974.  
  975. /*-----------------------------------------------------------------------------
  976. **    演奏中でなければ、演奏曲が変わることがないので、ポインタ 操作不要である.
  977. -----------------------------------------------------------------------------*/
  978.     if ( CDDA_NOW_status != CDDA_STAT_PLAY ) return ;
  979.  
  980. /*-----------------------------------------------------------------------------
  981. **    演奏中にもかかわらず 次の曲を示す ポインタ が先頭を示していることはない.
  982. **    そのためにとりあえず インクリメント しておく.
  983. -----------------------------------------------------------------------------*/
  984.     if ( CDDA_nplay <= CDDA_ZERO ) CDDA_nplay = 1 ;
  985.     switch ( CDDA_PLAY_mode ) {
  986.     case CDDA_SW_SHUFFLE :
  987.     case CDDA_SW_PROGRAM :
  988. /*-----------------------------------------------------------------------------
  989. **    シャッフルモード, プログラムモード時には、演奏曲を示すのに きちんと ポインタ を使用して
  990. **    いるので、あらためて チェック する必要がない.
  991. **    結構 チェック するのが、大変だったりするのですねぇ~.
  992. -----------------------------------------------------------------------------*/
  993.         break ;
  994.     case CDDA_SW_CONTINUE :
  995.     case CDDA_SW_SINGLE :
  996. /*-----------------------------------------------------------------------------
  997. **    シングルモード, CONTINUEモード時には、曲の順に正しく格納されているためと、演奏
  998. **    開始時とかに ポインタ を必ずしも使用していないので、チェック しておく.
  999. **
  1000. **    ようするに、デフォルトでこのように曲を管理領域に格納しているので、このような
  1001. **    状況となっている. また、ポインタ も初期状態は クリア されているため.
  1002. -----------------------------------------------------------------------------*/
  1003.         if ( CDDA_PLAY_no[CDDA_nplay-1] != CDDA_NOW_musicno ) {
  1004.             for ( c=CDDA_nplay; c<CDDA_MAX_TRACK; c++ ) {
  1005.                 if ( CDDA_PLAY_no[c] == CDDA_NOW_musicno ) {
  1006.                     CDDA_nplay = c + 1 ;
  1007.                     break ;
  1008.                 }
  1009.             }
  1010.         }
  1011.         break ;
  1012.     }
  1013. }
  1014.  
  1015. /**************************  CDの現在の状態を取得  *************************/
  1016. int CDDA_get_status( void )
  1017. /*=============================================================================
  1018. **    演奏状態の取得を行う.
  1019. **
  1020. **    < INPUT  > : なし
  1021. **    < OUTPUT > : なし
  1022. **    < RETURN > : エラー値
  1023. **
  1024. **    この関数を続けてCALLする場合には、100ms以上待ち時間をおいて下さい.
  1025. **    (この関数に限ったことではないのだが・・・・・)
  1026. **    たてつづけにCALLすると、演奏中の場合には、音飛びなどの原因となります.
  1027. **    何故なんだろう?困ったもんだ・・・
  1028. **
  1029. **    この関数は、毎秒2~3回CALLするようにして下さい. そうしないと、演奏モード
  1030. **    のとおりに演奏されません. また、演奏時間も保証されません.
  1031. =============================================================================*/
  1032. {
  1033.     int        ret ;
  1034.  
  1035.     if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
  1036.  
  1037.     CDDA_FLG_change = CDDA_FALSE ;
  1038.  
  1039.     ret = CDDA_mphase() ;
  1040.     if ( !ret ) {
  1041.         if ( CDDA_NOW_status ) {                    /*  演奏中                */
  1042. /*-----------------------------------------------------------------------------
  1043. **    演奏中である旨を フラグ セット する.
  1044. **    リピートフラグ は、停止中は無効で演奏に入った時点から有効とする.
  1045. **    CDDA_FLG_repeat が真値の時 リピート 指定あり.
  1046. **    CDDA_FLG_repeaton が真値の時 リピート有効 を表す.
  1047. -----------------------------------------------------------------------------*/
  1048.             CDDA_FLG_nowplay = CDDA_TRUE ;
  1049.             CDDA_FLG_cdstop  = CDDA_FALSE ;
  1050.             if ( CDDA_FLG_repeat ) CDDA_FLG_repeaton = CDDA_TRUE ;
  1051.             CDDA_nplay_check() ;
  1052.             CDDA_NOW_status = CDDA_STAT_PLAY ;
  1053.             CDDA_remaintime() ;                            /*  残り時間取得    */
  1054.         } else {                                    /*  停止中 or PAUSE中    */
  1055.             if ( CDDA_FLG_pause ) {                        /*  一時停止中        */
  1056.                 CDDA_FLG_nowplay = CDDA_TRUE ;
  1057.                 CDDA_FLG_cdstop  = CDDA_FALSE ;
  1058.                 if ( CDDA_FLG_repeat ) CDDA_FLG_repeaton = CDDA_TRUE ;
  1059.                 CDDA_NOW_status  = CDDA_STAT_PAUSE ;
  1060. /*-----------------------------------------------------------------------------
  1061. **    PAUSE中は、演奏情報を変更しない. 元に戻しておく.
  1062. **    PAUSE用の曲番号, 曲内経過時間は、FF/REW があれば変更される.
  1063. -----------------------------------------------------------------------------*/
  1064.                 CDDA_NOW_musicno = CDDA_NOW_pause ;
  1065.                 memcpy( (char *)&CDDA_CLOCK_nowtrack,
  1066.                         (char *)&CDDA_CLOCK_pause,
  1067.                         sizeof( CDDA_TRACK ) ) ;
  1068.             } else {                                    /*  停止中            */
  1069. /*-----------------------------------------------------------------------------
  1070. **    停止中を示すために各演奏状態を設定しておく.
  1071. **    ただし、停止中というのは、一時的なものもあるので、各変数を停止した状態
  1072. **    にしてはならない.
  1073. -----------------------------------------------------------------------------*/
  1074.                 CDDA_NOW_status  = CDDA_STAT_STOP ;
  1075.                 CDDA_NOW_musicno = CDDA_ZERO ;
  1076.                 CDDA_NOW_pause   = CDDA_ZERO ;
  1077.             }
  1078.             /*  残り時間        */
  1079.             CDDA_remaintime() ;
  1080.         }
  1081.         return( CDDA_ERR_NOERROR ) ;
  1082.     } else {
  1083.         if ( ret == CDDA_ERR_CHANGE ) {                /*  CD が入れ換えられた    */
  1084.             CDDA_FLG_change  = CDDA_TRUE ;
  1085.         }
  1086. /*-----------------------------------------------------------------------------
  1087. **    演奏状態が取得できない時には、CD が セット されていないものと判断する.
  1088. -----------------------------------------------------------------------------*/
  1089.  
  1090. /*    ↓↓                        ★★ DEBUG ★★                        ↓↓    */
  1091.         if ( CDDA_DEBUG ) {
  1092.             if ( ret == CDDA_ERR_NOTREADY ) {
  1093.                 printf("!") ;
  1094.             } else {
  1095.                 printf("\n<CDDA_get_status> get_status return : ") ;
  1096.                 CDDA_debug_dispmsg( ret ) ;
  1097.             }
  1098.         }
  1099. /*    ↑↑                        ★★ DEBUG ★★                        ↑↑    */
  1100.  
  1101.         CDDA_libinit() ;
  1102.         return( ret ) ;
  1103.     }
  1104. }
  1105.  
  1106. /****************************  演奏状態の取得とチェック  *************************/
  1107. int CDDA_status( void )
  1108. /*=============================================================================
  1109. **    演奏状態の取得とチェックを行う.
  1110. **
  1111. **    < INPUT  > : なし
  1112. **    < OUTPUT > : なし
  1113. **    < RETURN > : エラー値
  1114. **
  1115. **    この関数を続けてCALLする場合には、100ms以上待ち時間をおいて下さい.
  1116. **    (この関数に限ったことではないのだが・・・・・)
  1117. **    たてつづけにCALLすると、演奏中の場合には、音飛びなどの原因となります.
  1118. **    何故なんだろう?困ったもんだ・・・
  1119. **
  1120. **    この関数は、毎秒2~3回CALLするようにして下さい. そうしないと、演奏モード
  1121. **    のとおりに演奏されません. また、演奏時間も保証されません.
  1122. =============================================================================*/
  1123. {
  1124.     int        ret ;
  1125.  
  1126. /*-----------------------------------------------------------------------------
  1127. **    演奏状態を取得後に、各演奏モード毎に演奏状態が妥当かどうか チェック し、然る
  1128. **    べき処理の後、演奏状態が変わることがあるために、再度演奏状態を取得する
  1129. **    という アルゴリズム をとっている.
  1130. -----------------------------------------------------------------------------*/
  1131.  
  1132.     ret = CDDA_get_status() ;
  1133.     if ( ret ) {
  1134. /*-----------------------------------------------------------------------------
  1135. **    ステータス情報取得は、必ず成功を前提とする. 失敗した時には、CD が抜かれたと
  1136. **    みなす.
  1137. -----------------------------------------------------------------------------*/
  1138.  
  1139. /*    ↓↓                        ★★ DEBUG ★★                        ↓↓    */
  1140.         if ( CDDA_DEBUG ) {
  1141.             if ( ret == CDDA_ERR_NOTREADY ) {
  1142.                 printf("!") ;
  1143.             } else {
  1144.                 printf("\n<CDDA_status> get_status return : ") ;
  1145.                 CDDA_debug_dispmsg( ret ) ;
  1146.             }
  1147.         }
  1148. /*    ↑↑                        ★★ DEBUG ★★                        ↑↑    */
  1149.  
  1150.         CDDA_remaintime() ;
  1151.         return( ret ) ;
  1152.     }
  1153.  
  1154.     CDDA_FLG_stchange = CDDA_FALSE ;
  1155.     ret = CDDA_play_check() ;
  1156.  
  1157.     if ( !CDDA_FLG_stchange ) {
  1158.  
  1159. /*    ↓↓                        ★★ DEBUG ★★                        ↓↓    */
  1160.         if ( CDDA_DEBUG ) {
  1161.             if ( ret ) {
  1162.                 printf( "\n" ) ;
  1163.                 printf( "<CDDA_status> " ) ;
  1164.                 printf( "play_check return (not change status) : " ) ;
  1165.                 CDDA_debug_dispmsg( ret ) ;
  1166.                 printf( "\n" ) ;
  1167.             }
  1168.         }
  1169. /*    ↑↑                        ★★ DEBUG ★★                        ↑↑    */
  1170.  
  1171.         return( ret ) ;
  1172.     }
  1173.  
  1174.     if ( ret == CDDA_ERR_REPEAT ) return( ret ) ;
  1175.     if ( ret && ret != CDDA_ERR_REPEAT ) {
  1176.  
  1177. /*    ↓↓                        ★★ DEBUG ★★                        ↓↓    */
  1178.         if ( CDDA_DEBUG ) {
  1179.             printf( "\n<CDDA_status> play_check error return : " ) ;
  1180.             CDDA_debug_dispmsg( ret ) ;
  1181.             printf( "\n" ) ;
  1182.         }
  1183. /*    ↑↑                        ★★ DEBUG ★★                        ↑↑    */
  1184.  
  1185.         CDDA_NOW_musicno = CDDA_ZERO ;
  1186.         CDDA_NOW_pause   = CDDA_ZERO ;
  1187.         CDDA_nplay       = CDDA_ZERO ;
  1188.         CDDA_prgptr      = CDDA_ZERO ;
  1189.         CDDA_remaintime() ;
  1190.         return( ret ) ;
  1191.     }
  1192.  
  1193. /*    ↓↓                        ★★ DEBUG ★★                        ↓↓    */
  1194.     if ( CDDA_DEBUG ) {
  1195.         printf( "\n" ) ;
  1196.         printf( "<CDDA_status> " ) ;
  1197.         printf( "play_check return (status change) : " ) ;
  1198.         CDDA_debug_dispmsg( ret ) ;
  1199.         printf( "\n" ) ;
  1200.     }
  1201. /*    ↑↑                        ★★ DEBUG ★★                        ↑↑    */
  1202.  
  1203.     return( CDDA_get_status() ) ;
  1204. }
  1205.  
  1206. /****************************  時間指定演奏処理  *****************************/
  1207. int CDDA_timeplay( void )
  1208. /*=============================================================================
  1209. **    指定された時間の範囲内を演奏する.
  1210. **
  1211. **    < INPUT  > : なし
  1212. **    < OUTPUT > : なし
  1213. **    < RETURN > : エラー値
  1214. **
  1215. **    CDDA_CLOCK_start および CDDA_CLOCK_end を設定してからこの関数をCALLする
  1216. **    こと.
  1217. =============================================================================*/
  1218. {
  1219.     int        errcnt ;
  1220.  
  1221.     if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
  1222.  
  1223. #if 0
  1224. /*
  1225. **    PAUSE中に通常のPLAYは受け付けないようにする.
  1226. */
  1227.     if ( CDDA_FLG_pause && !CDDA_FLG_pauseplay ) return( CDDA_ERR_NOWPAUSE ) ;
  1228. #else
  1229. /*
  1230. **    PLAYならばPAUSEは無条件に解除する.
  1231. */
  1232.     CDDA_FLG_pause = CDDA_FALSE ;
  1233. #endif
  1234.  
  1235.     if ( !CDDA_FLG_tocread ) return( CDDA_ERR_NOTREADY ) ;
  1236.  
  1237. /*    ↓↓                        ★★ DEBUG ★★                        ↓↓    */
  1238.     if ( CDDA_DEBUG ) {
  1239.         printf( "<CDDA_timeplay> " ) ;
  1240.         printf( "start ~ end = %d ~ %d",
  1241.                 CDDA_NOW_start,CDDA_NOW_end ) ;
  1242.         printf( " , start-time : %d.%d.%d\n",CDDA_CLOCK_start.min,
  1243.                 CDDA_CLOCK_start.sec,CDDA_CLOCK_start.frame ) ;
  1244.     }
  1245. /*    ↑↑                        ★★ DEBUG ★★                        ↑↑    */
  1246.  
  1247. /*-----------------------------------------------------------------------------
  1248. **    CD の回転が安定するまでは、エラー となるので、リトライ 処理をしている.
  1249. -----------------------------------------------------------------------------*/
  1250.     errcnt = 0 ;
  1251.     do {
  1252.         if ( cdr_pause( CDDA_INFO_buf.drv ) == CDDA_ERR_CHANGE ) {
  1253.             CDDA_libinit() ;
  1254.             CDDA_FLG_change  = CDDA_TRUE ;
  1255.             return( CDDA_ERR_CHANGE ) ;
  1256.         }
  1257.         if ( CDDA_mtrplay() == CDDA_ERR_PARAMETER ) {    /*  演奏開始        */
  1258.             return( CDDA_ERR_PARAMETER ) ;
  1259.         }
  1260.         if ( CDDA_mphase() ) CDDA_NOW_status = CDDA_STAT_STOP ;
  1261.         if ( ++errcnt >= CDDA_RETRY ) {
  1262.  
  1263. /*    ↓↓                        ★★ DEBUG ★★                        ↓↓    */
  1264.             if ( CDDA_DEBUG ) {
  1265.                 printf("\n<CDDA_timeplay> NOT PLAY! retry count over.\n") ;
  1266.             }
  1267. /*    ↑↑                        ★★ DEBUG ★★                        ↑↑    */
  1268.  
  1269.             return( CDDA_ERR_PARAMETER ) ;
  1270.         }
  1271.     } while( CDDA_NOW_status != CDDA_STAT_PLAY ) ;
  1272.  
  1273. /*-----------------------------------------------------------------------------
  1274. **    演奏処理をしたら、演奏状態を取得してその返り値を返す.
  1275. -----------------------------------------------------------------------------*/
  1276.     return( CDDA_status() ) ;
  1277. }
  1278.  
  1279. /**************************  CDの演奏をします。 ****************************/
  1280. int CDDA_play( void )
  1281. /*=============================================================================
  1282. **    指定された曲を演奏する.
  1283. **
  1284. **    < INPUT  > : なし
  1285. **    < OUTPUT > : なし
  1286. **    < RETURN > : エラー値
  1287. **
  1288. **    CDDA_NOW_start および CDDA_NOW_end を設定してからこの関数をCALLすること.
  1289. **
  1290. **    ここでは、演奏開始曲と演奏終了曲に従って演奏処理をするので、演奏中に演奏
  1291. **    させない時などは、この関数を呼ぶ側で制御します.
  1292. **
  1293. **    時間指定による演奏などは、この関数を使用しないで、演奏開始/終了時間を設
  1294. **    定後 CDDA_timeplay() を CALL して下さい.
  1295. =============================================================================*/
  1296. {
  1297.     if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
  1298. /*
  1299. **    TOC 読み込み
  1300. */
  1301.     if ( !CDDA_FLG_tocread ) {
  1302.         if( CDDA_tocread() ) return( CDDA_ERR_NOTREADY ) ;
  1303.     }
  1304. /*
  1305. **    CDDA のないコンパクトディスクには用がない!
  1306. */
  1307.     if ( CDDA_INFO_buf.type != CDDA_TYPE_CDDA &&
  1308.             CDDA_INFO_buf.type != CDDA_TYPE_BOTH ) return( CDDA_ERR_NOMUSIC ) ;
  1309. /*
  1310. **    演奏曲番号誤り
  1311. */
  1312.     if ( CDDA_NOW_start < CDDA_MIN_TRACK ) return( CDDA_ERR_PARAMETER ) ;
  1313.     if ( CDDA_NOW_end > CDDA_MAX_TRACK )   return( CDDA_ERR_PARAMETER ) ;
  1314.     if ( CDDA_NOW_start > CDDA_NOW_end )   return( CDDA_ERR_PARAMETER ) ;
  1315.     if ( CDDA_NOW_start > CDDA_INFO_buf.end ||
  1316.             CDDA_NOW_end < CDDA_INFO_buf.start )
  1317.         return( CDDA_ERR_PARAMETER ) ;
  1318. /*
  1319. **    演奏時間設定
  1320. */
  1321.     CDDA_set_time_start( CDDA_NOW_start ) ;        /*  演奏開始曲データ設定    */
  1322.     CDDA_set_time_end( CDDA_NOW_end ) ;            /*  演奏終了曲データ設定    */
  1323. /*
  1324. **    演奏開始
  1325. */
  1326.     return( CDDA_timeplay() ) ;
  1327. }
  1328.  
  1329. /*************************  CD PAUSE/CONTINUE 処理  **************************/
  1330. int CDDA_pause( void )
  1331. /*=============================================================================
  1332. **    一時停止のON/OFFを行う.
  1333. **
  1334. **    < INPUT  > : なし
  1335. **    < OUTPUT > : なし
  1336. **    < RETURN > : エラー値
  1337. **
  1338. **    CDDA_FLG_pause をこの関数以外で操作しないこと.
  1339. **    また、当ライブラリ以外でCDのPAUSEやSTOPをしないこと.
  1340. =============================================================================*/
  1341. {
  1342.     int        ret ;
  1343.  
  1344.     ret = CDDA_status() ;                        /*  演奏状態のチェック            */
  1345.     if ( ret ) return( ret ) ;
  1346.  
  1347. /*-----------------------------------------------------------------------------
  1348. **    停止中とPAUSE中を見分けるために、ライブラリ内の フラグ で管理しています.
  1349. **    フラグ は、新たに演奏開始とか停止,エラーの場合などを除き、この関数内で制御し
  1350. **    ます.
  1351. -----------------------------------------------------------------------------*/
  1352.     if ( CDDA_NOW_status == CDDA_STAT_PAUSE ) {            /*  PAUSE中            */
  1353.         CDDA_FLG_pause = CDDA_FALSE ;
  1354. /*-----------------------------------------------------------------------------
  1355. **    PAUSE中に、別途指定した時間から演奏を開始する場合には、CDDA_FLG_pauseplay
  1356. **    を呼ぶ側で 真値 にしておきます.
  1357. -----------------------------------------------------------------------------*/
  1358.         if ( CDDA_FLG_pauseplay ) {                        /*  時間指定 PLAY    */
  1359.             ret = CDDA_timeplay() ;
  1360.             if ( ret == CDDA_ERR_CHANGE ) {                /*  CD入れ換え時    */
  1361.                 CDDA_libinit() ;
  1362.                 CDDA_FLG_change  = CDDA_TRUE ;
  1363.                 return( CDDA_ERR_CHANGE ) ;
  1364.             } else if ( ret == CDDA_ERR_PARAMETER ) {    /*  パラメタエラー        */
  1365.                 return( CDDA_ERR_PARAMETER ) ;
  1366.             }
  1367.         } else {                                        /*  CONTINUE        */
  1368.             if ( cdr_continue( CDDA_INFO_buf.drv ) == CDDA_ERR_CHANGE ) {
  1369.                 CDDA_libinit() ;
  1370.                 CDDA_FLG_change  = CDDA_TRUE ;
  1371.                 return( CDDA_ERR_CHANGE ) ;
  1372.             }
  1373.         }
  1374.  
  1375.     } else if ( CDDA_NOW_status == CDDA_STAT_PLAY ) {    /*  演奏中            */
  1376. /*-----------------------------------------------------------------------------
  1377. **    演奏中ならばPAUSEする前に演奏時間を保存しておき、PAUSEする.
  1378. -----------------------------------------------------------------------------*/
  1379.         ret = CDDA_status() ;
  1380.         CDDA_FLG_pauseplay = CDDA_FALSE ;
  1381.         if ( ret ) return( ret ) ;
  1382.         CDDA_FLG_pause = CDDA_TRUE ;
  1383.         CDDA_NOW_pause = CDDA_NOW_musicno ;
  1384.         CDDA_NOW_start = CDDA_NOW_musicno ;
  1385.         memcpy( (char *)&CDDA_CLOCK_pause,(char *)&CDDA_CLOCK_nowtrack,
  1386.                 sizeof( CDDA_TRACK ) ) ;
  1387.         ret = cdr_pause( CDDA_INFO_buf.drv ) ;
  1388.         if ( ret ) return( ret ) ;
  1389.  
  1390.     } else if ( CDDA_NOW_status == CDDA_STAT_STOP ) {    /*  停止中            */
  1391. /*-----------------------------------------------------------------------------
  1392. **    停止中ならば最初に演奏する曲の演奏情報だけを設定しておく.
  1393. -----------------------------------------------------------------------------*/
  1394.         CDDA_FLG_pause         = CDDA_TRUE ;
  1395.         CDDA_FLG_pauseplay     = CDDA_TRUE ;
  1396.         if ( CDDA_nplay > CDDA_ZERO ) {
  1397.             CDDA_NOW_start     = CDDA_PLAY_no[CDDA_nplay-1] ;
  1398.             CDDA_NOW_end       = CDDA_PLAY_no[CDDA_nplay-1] ;
  1399.         } else {
  1400.             CDDA_NOW_start     = CDDA_NOW_end = CDDA_PLAY_no[CDDA_ZERO] ;
  1401.         }
  1402.         if ( CDDA_NOW_start && CDDA_nplay == CDDA_ZERO ) CDDA_nplay ++ ;
  1403.         CDDA_NOW_musicno       = CDDA_NOW_pause = CDDA_NOW_start ;
  1404.         CDDA_set_time_start( CDDA_NOW_start ) ;    /*  演奏開始曲データ設定    */
  1405.         CDDA_set_time_end( CDDA_NOW_end ) ;        /*  演奏終了曲データ設定    */
  1406.         CDDA_CLOCK_nowtrack.min   = CDDA_ZERO ;
  1407.         CDDA_CLOCK_nowtrack.sec   = CDDA_ZERO ;
  1408.         CDDA_CLOCK_nowtrack.frame = CDDA_ZERO ;
  1409.         memcpy( (char *)&CDDA_CLOCK_pause,(char *)&CDDA_CLOCK_nowtrack,
  1410.                 sizeof( CDDA_TRACK ) ) ;
  1411.         ret = cdr_pause( CDDA_INFO_buf.drv ) ;
  1412.         if ( ret ) return( ret ) ;
  1413.  
  1414.     } else {                                            /*  NOT READY        */
  1415.         CDDA_FLG_pause     = CDDA_FALSE ;
  1416.         CDDA_FLG_pauseplay = CDDA_FALSE ;
  1417.     }
  1418.  
  1419.     return( CDDA_status() ) ;
  1420. }
  1421.  
  1422. /******************************  シャッフルの初期化 *******************************/
  1423. void CDDA_shuffle_init( void )
  1424. /*=============================================================================
  1425. **    シャッフルのための初期化を行う.
  1426. **
  1427. **    < INPUT  > : なし
  1428. **    < OUTPUT > : なし
  1429. **    < RETURN > : なし
  1430. **
  1431. **    乱数の初期化は、ライブラリの初期設定で行っておく.
  1432. =============================================================================*/
  1433. {
  1434.     int        c, cc ;                                /*  ループカウンタ                */
  1435.     int        music ;                                /*  乱数取得曲番号            */
  1436.     int        cnt ;                                /*  曲番号取得用(何番目か)    */
  1437.     char    flg[CDDA_MAX_TRACK] ;                /*  乱数取得曲番号用フラグ    */
  1438.  
  1439.     if ( !CDDA_FLG_tocread ) {                    /*  TOC 読み込み            */
  1440.         if( CDDA_tocread() ) return ;
  1441.     }
  1442.  
  1443. /*-----------------------------------------------------------------------------
  1444. **    初期化フラグをクリアするのは、ここだけである.
  1445. -----------------------------------------------------------------------------*/
  1446.     CDDA_FLG_shuffleinit = CDDA_FALSE ;            /*  シャッフル初期化フラグクリア        */
  1447.  
  1448.     CDDA_music_clear() ;                        /*  曲管理情報クリア            */
  1449.     for ( c=0; c<CDDA_MAX_TRACK; c++ ) {        /*  フラグ初期化                */
  1450.         flg[c] = CDDA_FALSE ;
  1451.     }
  1452.  
  1453. /*-----------------------------------------------------------------------------
  1454. **    全ての曲を ランダム な順に演奏するように セット する.
  1455. -----------------------------------------------------------------------------*/
  1456.     for ( c=CDDA_INFO_buf.end; c>0; c-- ) {
  1457.         music = CDDA_RANDOM( c ) + 1 ;
  1458.         cnt   = 0 ;
  1459.         for ( cc=0; cc<CDDA_INFO_buf.end; cc++ ) {
  1460.             if ( !flg[cc] ) cnt ++ ;
  1461.             if ( cnt == music ) {
  1462.                 flg[cc] = CDDA_TRUE ;
  1463.                 music = cc + 1 ;
  1464.                 break ;
  1465.             }
  1466.         }
  1467.         CDDA_PLAY_no[CDDA_INFO_buf.end-c] = music ;    /*  曲番号格納            */
  1468.     }
  1469. }
  1470.  
  1471. /***************************  シャッフルの曲番号を返す ****************************/
  1472. int CDDA_shuffle( int *nextno )
  1473. /*=============================================================================
  1474. **    シャッフルのための曲番号を取得する.
  1475. **
  1476. **    < INPUT  > : なし
  1477. **    < OUTPUT > : 次の演奏曲番号, 終了時は 偽値.
  1478. **    < RETURN > : エラー値
  1479. **
  1480. **    この関数を最初に呼ぶ時には、必ず初期化フラグ(CDDA_FLG_shuffleinit)を真値に
  1481. **    しておくこと.
  1482. =============================================================================*/
  1483. {
  1484.     if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
  1485.  
  1486.     if ( CDDA_PLAY_mode != CDDA_SW_SHUFFLE ) return( CDDA_ERR_PARAMETER ) ;
  1487.  
  1488.     *nextno = CDDA_ZERO ;
  1489. /*
  1490. **    TOC 読み込み
  1491. */
  1492.     if ( !CDDA_FLG_tocread ) {
  1493.         if( CDDA_tocread() ) return( CDDA_ERR_NOTREADY ) ;
  1494. /*
  1495. **    CDDA のないコンパクトディスクには用がない!
  1496. */
  1497.         if ( CDDA_INFO_buf.type != CDDA_TYPE_CDDA &&
  1498.                 CDDA_INFO_buf.type != CDDA_TYPE_BOTH )
  1499.             return( CDDA_ERR_NOMUSIC ) ;
  1500.     }
  1501.  
  1502. /*
  1503. **    シャッフル処理
  1504. */
  1505.     if ( CDDA_FLG_shuffleinit )                    /*  シャッフル情報初期化            */
  1506.         CDDA_shuffle_init() ;
  1507.  
  1508. /*-----------------------------------------------------------------------------
  1509. **    次の曲を求める. 終了時には、曲番号が 0 で返り値が エラー値(真値)となる.
  1510. **    次の曲番号は、CDDA_NOW_start に セット されてくる.
  1511. -----------------------------------------------------------------------------*/
  1512.     if ( CDDA_next_music() )                    /*  全ての曲を終了した        */
  1513.         return( CDDA_ERR_PARAMETER ) ;
  1514.  
  1515.     *nextno = CDDA_NOW_start ;
  1516.     CDDA_NOW_pause = CDDA_NOW_musicno = CDDA_NOW_start ;
  1517.     CDDA_CLOCK_nowtrack.min   = CDDA_ZERO ;
  1518.     CDDA_CLOCK_nowtrack.sec   = CDDA_ZERO ;
  1519.     CDDA_CLOCK_nowtrack.frame = CDDA_ZERO ;
  1520.     memcpy( (char *)&CDDA_CLOCK_pause,(char *)&CDDA_CLOCK_nowtrack,
  1521.             sizeof( CDDA_TRACK ) ) ;
  1522.  
  1523.     return( CDDA_ERR_NOERROR ) ;
  1524. }
  1525.  
  1526. /**************************  プログラムの曲番号を確認 ***************************/
  1527. int CDDA_program_data_check( void )
  1528. /*=============================================================================
  1529. **    プログラムの曲番号を確認する.
  1530. **
  1531. **    < INPUT  > : なし
  1532. **    < OUTPUT > : なし
  1533. **    < RETURN > : 何曲目( 終了時は、0 : 最後の曲の場合には、-1 )
  1534. **
  1535. **    次の曲番号(確認したい曲番号)は、CDDA_NOW_musicno に セット します.
  1536. **    プログラム登録曲数は、CDDA_TOTAL_program に セット されてます.
  1537. **    残り演奏曲数は、CDDA_REMAIN_program に セット されてます.
  1538. **    確認用の曲が何曲目 (演奏中または演奏開始曲を 1 として) かを 
  1539. **    CDDA_COUNT_program に セット します.
  1540. **
  1541. **    演奏ポインタ(CDDA_nplay), プログラムポインタ(CDDA_prgptr)の扱いに注意.
  1542. =============================================================================*/
  1543. {
  1544.     CDDA_COUNT_program = CDDA_ZERO ;
  1545.  
  1546.     if ( !CDDA_FLG_tocread ) return( CDDA_ZERO ) ;
  1547.     if ( CDDA_PLAY_mode != CDDA_SW_PROGRAM ) return( CDDA_ZERO ) ;
  1548.  
  1549. /*    ↓↓                        ★★ DEBUG ★★                        ↓↓    */
  1550.     if ( CDDA_DEBUG ) {
  1551.         printf( "<CDDA_program_data_check> " ) ;
  1552.         printf( "prgptr = %d , nplay = %d , 登録曲数(残り) = %d(%d)\n",
  1553.                 CDDA_prgptr,CDDA_nplay,
  1554.                 CDDA_TOTAL_program,CDDA_REMAIN_program ) ;
  1555.     }
  1556. /*    ↑↑                        ★★ DEBUG ★★                        ↑↑    */
  1557.  
  1558. /*-----------------------------------------------------------------------------
  1559. **    プログラムポインタ が クリア されている時には、今演奏中の曲番号の位置をスタート(0)と
  1560. **    する. (通常は、クリア されているか 最後に曲を追加できるような位置になって
  1561. **    いる.)
  1562. **
  1563. **    アプリケーション側で、プログラム確認中にある程度時間がたったら、ポインタ を クリア する
  1564. **    ようになっていることを想定している.
  1565. -----------------------------------------------------------------------------*/
  1566.     if ( CDDA_prgptr == CDDA_ZERO ) {
  1567.         CDDA_prgptr = CDDA_nplay ;
  1568.         if ( CDDA_prgptr > CDDA_ZERO ) CDDA_prgptr -- ;
  1569.     }
  1570.  
  1571. /*-----------------------------------------------------------------------------
  1572. **    最後の曲よりも後ろを ポインタ を指していた場合には、これで終わりだという意
  1573. *    味で、ポインタ を クリア し、曲番号には 0 を セット しておく.
  1574. -----------------------------------------------------------------------------*/
  1575.     if ( CDDA_PLAY_no[CDDA_prgptr] == CDDA_ZERO ) {
  1576. /*
  1577. **    時間情報設定
  1578. */
  1579.         CDDA_NOW_musicno    = CDDA_ZERO ;
  1580.         CDDA_prgptr         = CDDA_ZERO ;
  1581.         CDDA_COUNT_program  = CDDA_ZERO ;
  1582.         CDDA_CLOCK_nowtrack.min   = CDDA_ZERO ;
  1583.         CDDA_CLOCK_nowtrack.sec   = CDDA_ZERO ;
  1584.         CDDA_CLOCK_nowtrack.frame = CDDA_ZERO ;
  1585.         /*  残り時間計算        */
  1586.         CDDA_program_remaintime() ;
  1587.         return( CDDA_ZERO ) ;
  1588.  
  1589.     } else {
  1590. /*-----------------------------------------------------------------------------
  1591. **    プログラムポインタ を一つすすめる.
  1592. -----------------------------------------------------------------------------*/
  1593.         CDDA_prgptr ++ ;
  1594. /*
  1595. **    時間情報設定
  1596. */
  1597.         CDDA_NOW_musicno = CDDA_PLAY_no[CDDA_prgptr-1] ;
  1598.  
  1599.         /*  プログラム設定合計時間    */
  1600. /*-----------------------------------------------------------------------------
  1601. **    プログラムポインタ と 演奏ポインタ が等しく(プログラム確認した曲が現在演奏中の曲の時)
  1602. **    て、現在 PAUSE状態の時には、PAUSEした時点までの時間が演奏済である.
  1603. -----------------------------------------------------------------------------*/
  1604.         if ( CDDA_NOW_status == CDDA_STAT_PAUSE &&
  1605.                 CDDA_nplay == CDDA_prgptr ) {
  1606.             memcpy( (char *)&CDDA_CLOCK_nowtrack,(char *)&CDDA_CLOCK_pause,
  1607.                     sizeof( CDDA_TRACK ) ) ;
  1608.         } else {
  1609.             CDDA_CLOCK_nowtrack.min   = CDDA_ZERO ;
  1610.             CDDA_CLOCK_nowtrack.sec   = CDDA_ZERO ;
  1611.             CDDA_CLOCK_nowtrack.frame = CDDA_ZERO ;
  1612.         }
  1613.         /*  残り時間計算        */
  1614.         CDDA_program_remaintime() ;
  1615.  
  1616. /*-----------------------------------------------------------------------------
  1617. **    確認曲番号が何曲目かを CDDA_COUNT_program に セット しておく.
  1618. **    確認曲の次の曲がなければ、最後の曲だということで、-1 で リターン する.
  1619. -----------------------------------------------------------------------------*/
  1620.         if ( CDDA_nplay < 1 ) {
  1621.             CDDA_COUNT_program = CDDA_prgptr ;
  1622.         } else {
  1623.             CDDA_COUNT_program = CDDA_prgptr - CDDA_nplay + 1 ;
  1624.         }
  1625.         if ( CDDA_PLAY_no[CDDA_prgptr] == CDDA_ZERO ) {
  1626.             return( -1 ) ;
  1627.         } else {
  1628.             return( CDDA_COUNT_program ) ;
  1629.         }
  1630.     }
  1631. }
  1632.  
  1633. /**************************  プログラムの曲番号を削除 ***************************/
  1634. int CDDA_program_data_clear( void )
  1635. /*=============================================================================
  1636. **    プログラムの曲番号を削除する.
  1637. **
  1638. **    < INPUT  > : なし
  1639. **    < OUTPUT > : なし
  1640. **    < RETURN > : 削除した曲番号(削除できない時は 0)
  1641. **
  1642. **    プログラム登録曲数は、CDDA_TOTAL_program に セット します.
  1643. **    残り演奏曲数は、CDDA_REMAIN_program に セット します.
  1644. **    確認用の曲が何曲目 (演奏中または演奏開始曲を 1 として) かを
  1645. **    CDDA_COUNT_program に セット します.
  1646. **
  1647. **    削除によって更新された確認用の曲番号は、CDDA_NOW_musicno に セット します.
  1648. =============================================================================*/
  1649. {
  1650.     int        c ;
  1651.     int        delno ;
  1652.     char    playdel ;
  1653.     char    flg ;
  1654.     char    prgclear ;
  1655.  
  1656.     CDDA_COUNT_program = CDDA_ZERO ;
  1657.  
  1658.     if ( !CDDA_FLG_tocread ) return( CDDA_ZERO ) ;
  1659.     if ( CDDA_PLAY_mode != CDDA_SW_PROGRAM ) return( CDDA_ZERO ) ;
  1660.  
  1661. /*-----------------------------------------------------------------------------
  1662. **    一曲も登録されていない時には、データ削除しない.
  1663. -----------------------------------------------------------------------------*/
  1664.     if ( CDDA_TOTAL_program <= CDDA_ZERO ) return( CDDA_ZERO ) ;
  1665.     if ( CDDA_REMAIN_program <= CDDA_ZERO ) return( CDDA_ZERO ) ;
  1666.  
  1667. /*-----------------------------------------------------------------------------
  1668. **    プログラムポインタ が クリア されている時には、最後に登録してある曲を削除する.
  1669. **    通常は、プログラム確認中の曲を削除する.
  1670. -----------------------------------------------------------------------------*/
  1671.     if ( CDDA_prgptr > CDDA_ZERO ) {
  1672.         delno = CDDA_PLAY_no[CDDA_prgptr-1] ;
  1673.     } else {
  1674.         delno = CDDA_PLAY_no[CDDA_TOTAL_program-1] ;
  1675.     }
  1676.  
  1677. /*
  1678. **    データ 削除
  1679. */
  1680.     playdel = CDDA_FALSE ;
  1681.     if ( CDDA_prgptr > CDDA_ZERO ) {
  1682.         for ( c=CDDA_prgptr-1; c<CDDA_TOTAL_program; c++ ) {
  1683.             CDDA_PLAY_no[c] = CDDA_PLAY_no[c+1] ;
  1684.         }
  1685. /*-----------------------------------------------------------------------------
  1686. **    今演奏中の曲(かそれよりも前の曲)を削除した場合
  1687. -----------------------------------------------------------------------------*/
  1688.         if ( CDDA_nplay >= CDDA_prgptr && CDDA_nplay > CDDA_ZERO ) {
  1689.             CDDA_nplay -- ;
  1690.             playdel = CDDA_TRUE ;
  1691.         }
  1692. /*-----------------------------------------------------------------------------
  1693. **    最後の曲を削除した場合(プログラムポインタが最後の曲を指していた時)には、プログラム
  1694. **    ポインタ を更新しておく.
  1695. -----------------------------------------------------------------------------*/
  1696.         if ( CDDA_prgptr == CDDA_TOTAL_program ) CDDA_prgptr -- ;
  1697.     } else {
  1698.         CDDA_PLAY_no[CDDA_TOTAL_program-1] = CDDA_ZERO ;
  1699. /*-----------------------------------------------------------------------------
  1700. **    今演奏中の曲(かそれよりも前の曲)を削除した場合
  1701. -----------------------------------------------------------------------------*/
  1702.         if ( CDDA_nplay == CDDA_TOTAL_program ) {
  1703.             CDDA_nplay -- ;
  1704.             playdel = CDDA_TRUE ;
  1705.         }
  1706.     }
  1707.  
  1708. /*-----------------------------------------------------------------------------
  1709. **    削除後の確認曲番号を CDDA_NOW_musicno に セット しておく.
  1710. **    削除後の確認曲番号が何曲目かを CDDA_COUNT_program に セット しておく.
  1711. **    演奏中(PAUSE含)の曲を削除した場合には、次の曲の処理をする.
  1712. -----------------------------------------------------------------------------*/
  1713.     prgclear = CDDA_FALSE ;
  1714.     if ( playdel ) {
  1715.  
  1716. /*    ↓↓                        ★★ DEBUG ★★                        ↓↓    */
  1717.         if ( CDDA_DEBUG ) {
  1718.             printf( "<CDDA_program_data_clear> " ) ;
  1719.             printf( "演奏曲削除(status:%xh) : prgptr = %d , nplay = %d",
  1720.                     CDDA_NOW_status,CDDA_prgptr,CDDA_nplay ) ;
  1721.             printf( " , 削除曲 = %d , 登録曲数(残り) = %d(%d)\n",
  1722.                     delno,CDDA_TOTAL_program,CDDA_REMAIN_program ) ;
  1723.         }
  1724. /*    ↑↑                        ★★ DEBUG ★★                        ↑↑    */
  1725.  
  1726.         /*    ●●● 演奏中(PAUSE含む)の曲を削除した時 ●●●    */
  1727.         CDDA_TOTAL_program -- ;
  1728.         switch ( CDDA_NOW_status ) {
  1729. /*-----------------------------------------------------------------------------
  1730. **    今演奏中の曲を削除した場合には、次の曲を演奏する.
  1731. **    次の曲がなければ、演奏終了し、プログラム全てを クリア する.
  1732. **    CDDA_prgptr は、CDDA_next_music() で クリア されることに注意して設定する.
  1733. -----------------------------------------------------------------------------*/
  1734.         case CDDA_STAT_PLAY :
  1735.             if ( !CDDA_next_music() ) {
  1736.                 CDDA_NOW_musicno   = CDDA_NOW_start ;
  1737.                 CDDA_COUNT_program = 1 ;
  1738.                 CDDA_prgptr = CDDA_nplay ;
  1739.                 CDDA_play() ;
  1740.             } else {
  1741.                 if ( !CDDA_FLG_repeaton ) {
  1742.                     CDDA_music_clear() ;        /*  曲管理情報クリア            */
  1743.                     CDDA_FLG_nowplay = CDDA_FALSE ;
  1744.                     prgclear = CDDA_TRUE ;
  1745.                 } else {                        /*  リピート処理                */
  1746.                     CDDA_FLG_prgrepeat = CDDA_TRUE ;
  1747.                 }
  1748.                 cdr_mstop( CDDA_INFO_buf.drv ) ;
  1749.                 CDDA_NOW_musicno   = CDDA_ZERO ;
  1750.                 CDDA_COUNT_program = CDDA_ZERO ;
  1751.             }
  1752.             break ;
  1753. /*-----------------------------------------------------------------------------
  1754. **    今PAUSE中の曲を削除した場合には、次の曲を演奏開始状態とする.
  1755. **    次の曲がなければ、演奏終了し、プログラム全てを クリア する.
  1756. **    CDDA_prgptr は、CDDA_next_music() で クリア されることに注意して設定する.
  1757. -----------------------------------------------------------------------------*/
  1758.         case CDDA_STAT_PAUSE :
  1759.             if ( CDDA_ffmusic() ) {
  1760.                 if ( !CDDA_FLG_repeaton ) {        /*  終了処理                */
  1761.                     CDDA_music_clear() ;        /*  曲管理情報クリア            */
  1762.                     CDDA_FLG_nowplay = CDDA_FALSE ;
  1763.                     CDDA_FLG_pause   = CDDA_FALSE ;
  1764.                     prgclear = CDDA_TRUE ;
  1765.                 } else {                        /*  リピート処理                */
  1766.                     CDDA_FLG_prgrepeat = CDDA_TRUE ;
  1767.                 }
  1768.                 cdr_mstop( CDDA_INFO_buf.drv ) ;
  1769.                 CDDA_NOW_musicno   = CDDA_ZERO ;
  1770.                 CDDA_COUNT_program = CDDA_ZERO ;
  1771.             } else {
  1772.                 CDDA_COUNT_program = 1 ;
  1773.                 CDDA_prgptr = CDDA_nplay ;
  1774.             }
  1775.         }
  1776.     } else {
  1777.         if ( CDDA_prgptr > CDDA_ZERO ) {
  1778.             CDDA_NOW_musicno = CDDA_PLAY_no[CDDA_prgptr-1] ;
  1779.             if ( CDDA_nplay < 1 ) {
  1780.                 CDDA_COUNT_program = CDDA_prgptr ;
  1781.             } else {
  1782.                 CDDA_COUNT_program = CDDA_prgptr - CDDA_nplay + 1 ;
  1783.             }
  1784.         } else {
  1785. /*-----------------------------------------------------------------------------
  1786. **    プログラムポインタ が クリア されている時には、最後に登録してある曲が削除されるの
  1787. **    で、そのひとつ前の曲が確認曲となる. ( 2曲以上登録されているかどうか)
  1788. -----------------------------------------------------------------------------*/
  1789.             if ( CDDA_TOTAL_program > 1 ) {
  1790.                 CDDA_NOW_musicno   = CDDA_PLAY_no[CDDA_TOTAL_program-2] ;
  1791.                 CDDA_COUNT_program = CDDA_REMAIN_program - 1 ;
  1792.             } else {
  1793.                 CDDA_NOW_musicno   = CDDA_ZERO ;
  1794.                 CDDA_COUNT_program = CDDA_ZERO ;
  1795.             }
  1796.         }
  1797.     }
  1798.  
  1799. /*
  1800. **    時間情報設定
  1801. */
  1802.     if ( delno && !prgclear ) {
  1803. /*-----------------------------------------------------------------------------
  1804. **    データ 削除ありの時(プログラム演奏時間の更新)
  1805. **    ただし、演奏中(PAUSE含)の曲を削除した時に、停止処理をした場合を除く.
  1806. -----------------------------------------------------------------------------*/
  1807.         /*  プログラム設定合計時間    */
  1808.         CDDA_subtime( CDDA_TIME_program.min,
  1809.                 CDDA_TIME_program.sec,
  1810.                 CDDA_TIME_program.frame,
  1811.                 CDDA_TIME_track[delno-1].min,
  1812.                 CDDA_TIME_track[delno-1].sec,
  1813.                 CDDA_TIME_track[delno-1].frame,
  1814.                 &CDDA_TIME_program.min,
  1815.                 &CDDA_TIME_program.sec,
  1816.                 &CDDA_TIME_program.frame ) ;
  1817. /*-----------------------------------------------------------------------------
  1818. **    プログラム登録されていない曲の合計時間を求める.
  1819. -----------------------------------------------------------------------------*/
  1820.         flg = CDDA_TRUE ;
  1821.         for ( c=0; c<CDDA_TOTAL_program; c++ ) {
  1822.             if ( CDDA_PLAY_no[c] == delno ) {    /*  削除曲の登録はまだある    */
  1823.                 flg = CDDA_FALSE ;
  1824.                 break ;
  1825.             }
  1826.         }
  1827.         if ( flg ) {
  1828.             CDDA_addtime( CDDA_TIME_program2.min,
  1829.                     CDDA_TIME_program2.sec,
  1830.                     CDDA_TIME_program2.frame,
  1831.                     CDDA_TIME_track[delno-1].min,
  1832.                     CDDA_TIME_track[delno-1].sec,
  1833.                     CDDA_TIME_track[delno-1].frame,
  1834.                     &CDDA_TIME_program2.min,
  1835.                     &CDDA_TIME_program2.sec,
  1836.                     &CDDA_TIME_program2.frame ) ;
  1837.         }
  1838.     }
  1839.  
  1840. /*-----------------------------------------------------------------------------
  1841. **    プログラム登録曲数を一つ減らす.
  1842. -----------------------------------------------------------------------------*/
  1843.     if ( delno && !playdel ) {
  1844.         CDDA_TOTAL_program -- ;
  1845.         CDDA_REMAIN_program -- ;
  1846.     }
  1847.  
  1848.     /*  曲内経過時間        */
  1849.     CDDA_CLOCK_nowtrack.min   = CDDA_ZERO ;
  1850.     CDDA_CLOCK_nowtrack.sec   = CDDA_ZERO ;
  1851.     CDDA_CLOCK_nowtrack.frame = CDDA_ZERO ;
  1852.  
  1853.     /*  残り時間計算        */
  1854.     CDDA_program_remaintime() ;
  1855.  
  1856. /*-----------------------------------------------------------------------------
  1857. **    演奏中(PAUSE含)の曲を削除した時に停止処理をした場合は、時間をクリアしておく.
  1858. -----------------------------------------------------------------------------*/
  1859.     if ( playdel && !CDDA_NOW_musicno ) {
  1860.         CDDA_CLOCK_program.min   = CDDA_ZERO ;
  1861.         CDDA_CLOCK_program.sec   = CDDA_ZERO ;
  1862.         CDDA_CLOCK_program.frame = CDDA_ZERO ;
  1863.     }
  1864.  
  1865.     return( delno ) ;
  1866. }
  1867.  
  1868. /**************************  プログラムの曲番号を追加 ***************************/
  1869. int CDDA_program_data_add( int musicno )
  1870. /*=============================================================================
  1871. **    プログラムの曲番号を追加する.
  1872. **
  1873. **    < INPUT  > : 曲番号
  1874. **    < OUTPUT > : なし
  1875. **    < RETURN > : エラー値(最大登録数99を越えた場合にパラメタエラー値を返す)
  1876. **
  1877. **    プログラム登録曲数は、CDDA_TOTAL_program に セット します.
  1878. **    確認用の曲が何曲目 (演奏中または演奏開始曲を 1 として) かを 
  1879. **    CDDA_COUNT_program に セット します.
  1880. =============================================================================*/
  1881. {
  1882.     int        c ;
  1883.     char    flg ;
  1884.  
  1885.     CDDA_COUNT_program = CDDA_ZERO ;
  1886.  
  1887.     if ( !CDDA_FLG_tocread ) return( CDDA_ZERO ) ;
  1888.     if ( CDDA_PLAY_mode != CDDA_SW_PROGRAM ) return( CDDA_ZERO ) ;
  1889.  
  1890.     if ( CDDA_TOTAL_program >= CDDA_MAX_TRACK ) return( CDDA_ERR_PARAMETER ) ;
  1891.  
  1892. /*-----------------------------------------------------------------------------
  1893. **    プログラム登録されていない曲の合計時間を求める.
  1894. -----------------------------------------------------------------------------*/
  1895.     flg = CDDA_TRUE ;
  1896.     for ( c=0; c<CDDA_TOTAL_program; c++ ) {
  1897.         if ( CDDA_PLAY_no[c] == musicno ) {        /*  既に登録済の曲の追加    */
  1898.             flg = CDDA_FALSE ;
  1899.             break ;
  1900.         }
  1901.     }
  1902.     if ( flg ) {
  1903.         CDDA_subtime( CDDA_TIME_program2.min,
  1904.                 CDDA_TIME_program2.sec,
  1905.                 CDDA_TIME_program2.frame,
  1906.                 CDDA_TIME_track[musicno-1].min,
  1907.                 CDDA_TIME_track[musicno-1].sec,
  1908.                 CDDA_TIME_track[musicno-1].frame,
  1909.                 &CDDA_TIME_program2.min,
  1910.                 &CDDA_TIME_program2.sec,
  1911.                 &CDDA_TIME_program2.frame ) ;
  1912.     }
  1913.  
  1914. /*-----------------------------------------------------------------------------
  1915. **    プログラム曲追加時には、プログラムポインタを リセット しておく.
  1916. **    (データ削除および続けてデータ追加を行う時のため)
  1917. -----------------------------------------------------------------------------*/
  1918.     CDDA_prgptr = CDDA_ZERO ;
  1919.     CDDA_PLAY_no[CDDA_TOTAL_program] = musicno ;
  1920.  
  1921. /*
  1922. **    時間情報設定
  1923. */
  1924.     CDDA_NOW_musicno = musicno ;
  1925.  
  1926.     /*  プログラム設定合計時間    */
  1927.     CDDA_addtime( CDDA_TIME_program.min,
  1928.             CDDA_TIME_program.sec,
  1929.             CDDA_TIME_program.frame,
  1930.             CDDA_TIME_track[musicno-1].min,
  1931.             CDDA_TIME_track[musicno-1].sec,
  1932.             CDDA_TIME_track[musicno-1].frame,
  1933.             &CDDA_TIME_program.min,
  1934.             &CDDA_TIME_program.sec,
  1935.             &CDDA_TIME_program.frame ) ;
  1936.  
  1937.     /*  曲内経過時間        */
  1938.     if ( CDDA_TOTAL_program || CDDA_NOW_status == CDDA_STAT_STOP ) {
  1939. /*-----------------------------------------------------------------------------
  1940. **    一番最初に登録された曲は、演奏中またはPAUSE中であることがあるので、経過
  1941. **    時間を クリア しない.
  1942. -----------------------------------------------------------------------------*/
  1943.         CDDA_CLOCK_nowtrack.min   = CDDA_ZERO ;
  1944.         CDDA_CLOCK_nowtrack.sec   = CDDA_ZERO ;
  1945.         CDDA_CLOCK_nowtrack.frame = CDDA_ZERO ;
  1946.     }
  1947.  
  1948.     /*  残り時間計算        */
  1949.     CDDA_program_remaintime() ;
  1950.  
  1951. /*-----------------------------------------------------------------------------
  1952. **    プログラム登録曲数を一つ増やす.
  1953. -----------------------------------------------------------------------------*/
  1954.     CDDA_TOTAL_program ++ ;
  1955.     CDDA_REMAIN_program ++ ;
  1956.  
  1957. /*-----------------------------------------------------------------------------
  1958. **    追加後の確認曲番号が何曲目かを CDDA_COUNT_program に セット しておく.
  1959. -----------------------------------------------------------------------------*/
  1960.     CDDA_COUNT_program = CDDA_REMAIN_program ;
  1961.  
  1962.     return( CDDA_ERR_NOERROR ) ;
  1963. }
  1964.  
  1965. /*****************************  演奏初期ステータス取得  ***************************/
  1966. void CDDA_initstatus( void )
  1967. /*=============================================================================
  1968. **    演奏初期化処理時のステータス取得を行う.
  1969. **
  1970. **    < INPUT  > : なし
  1971. **    < OUTPUT > : なし
  1972. **    < RETURN > : なし
  1973. =============================================================================*/
  1974. {
  1975.     int        ret ;
  1976.  
  1977. /*-----------------------------------------------------------------------------
  1978. **    CD が入れ換えられた直後の時のために エラー値が真ならば再度 ステータス取得を行う.
  1979. -----------------------------------------------------------------------------*/
  1980.     ret = CDDA_mphase() ;
  1981.     if ( ret ) {
  1982.         ret = CDDA_mphase() ;
  1983.     }
  1984.  
  1985.     if ( !ret ) {
  1986.         if ( CDDA_NOW_status ) {                    /*  演奏中                */
  1987.             CDDA_FLG_nowplay = CDDA_TRUE ;
  1988.             CDDA_FLG_cdstop  = CDDA_FALSE ;
  1989.             if ( CDDA_FLG_repeat ) CDDA_FLG_repeaton = CDDA_TRUE ;
  1990.             CDDA_nplay_check() ;
  1991.             CDDA_NOW_status = CDDA_STAT_PLAY ;
  1992.         } else {                                    /*  停止中                */
  1993.             CDDA_NOW_status  = CDDA_STAT_STOP ;
  1994.             CDDA_NOW_musicno = CDDA_ZERO ;
  1995.             CDDA_NOW_pause   = CDDA_ZERO ;
  1996.         }
  1997.     } else {
  1998.         CDDA_libinit() ;                            /*  NOT READY            */
  1999.     }
  2000. }
  2001.  
  2002. /******************************  演奏初期化処理  *****************************/
  2003. int CDDA_swinit( void )
  2004. /*=============================================================================
  2005. **    演奏関係の初期処理を行う.
  2006. **
  2007. **    < INPUT  > : なし
  2008. **    < OUTPUT > : なし
  2009. **    < RETURN > : エラー値
  2010. **
  2011. **    当ライブラリ内の使用にあたっては、必ず最初にこの関数をCALLして下さい.
  2012. =============================================================================*/
  2013. {
  2014.     int        musicno ;
  2015.     CDDA_TRACK    nowtrack ;
  2016.  
  2017.     if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
  2018.  
  2019.     CDDA_initstatus() ;
  2020.     memcpy( (char *)&nowtrack,(char *)&CDDA_CLOCK_nowtrack,
  2021.             sizeof( CDDA_TRACK ) ) ;
  2022.  
  2023.     switch ( CDDA_NOW_status ) {
  2024.     case CDDA_STAT_NOTREADY :
  2025.         CDDA_libinit() ;
  2026.         return( CDDA_ERR_NOTREADY ) ;
  2027.     case CDDA_STAT_STOP :
  2028. /*-----------------------------------------------------------------------------
  2029. **    CD が セット されている時には、TOC を読み込む.
  2030. -----------------------------------------------------------------------------*/
  2031.         if( CDDA_tocread() ) return( CDDA_ERR_NOTREADY ) ;
  2032.         return( CDDA_status() ) ;
  2033.     case CDDA_STAT_PAUSE :
  2034.         return( CDDA_ERR_NOERROR ) ;
  2035.     case CDDA_STAT_PLAY :
  2036. /*-----------------------------------------------------------------------------
  2037. **    プログラム起動時に、演奏中だった場合には 一旦PAUSEして TOC 情報を取得し、
  2038. **    その後演奏を続ける.
  2039. -----------------------------------------------------------------------------*/
  2040.         musicno = CDDA_NOW_musicno ;
  2041.         if( CDDA_tocread() ) return( CDDA_ERR_NOTREADY ) ;
  2042.         CDDA_nplay = musicno ;
  2043.         CDDA_set_time_start( musicno ) ;
  2044.         CDDA_addtime( CDDA_CLOCK_start.min,
  2045.                 CDDA_CLOCK_start.sec,
  2046.                 CDDA_CLOCK_start.frame,
  2047.                 nowtrack.min,
  2048.                 nowtrack.sec,
  2049.                 nowtrack.frame,
  2050.                 &CDDA_CLOCK_start.min,
  2051.                 &CDDA_CLOCK_start.sec,
  2052.                 &CDDA_CLOCK_start.frame ) ;
  2053.         CDDA_NOW_start = CDDA_INFO_buf.start ;
  2054.         CDDA_NOW_end   = CDDA_INFO_buf.end ;
  2055.         CDDA_set_time_end( CDDA_NOW_end ) ;
  2056.         CDDA_timeplay() ;
  2057.         return( CDDA_status() ) ;
  2058.     }
  2059. }
  2060.  
  2061. /*******************************  演奏停止処理  ******************************/
  2062. void CDDA_select_stop( int mode )
  2063. /*=============================================================================
  2064. **    STOPキーが入力された時の処理を行う.
  2065. **
  2066. **    < INPUT  > : スイッチキー
  2067. **    < OUTPUT > : なし
  2068. **    < RETURN > : なし
  2069. =============================================================================*/
  2070. {
  2071.     int        c ;
  2072.  
  2073.     switch ( mode ) {
  2074.     /*  ●●● 終了処理 ●●●    */
  2075.     case CDDA_SW_EJECT :                        /*  強制停止                */
  2076. /*    case CDDA_SW_EXIT :    は CDDA_SW_EJECT と同じ    */
  2077. /*-----------------------------------------------------------------------------
  2078. **    CD 回転停止時間(最大値 255sec に)設定
  2079. -----------------------------------------------------------------------------*/
  2080.         cdr_pause( CDDA_INFO_buf.drv ) ;
  2081.         cdr_stptime( CDDA_INFO_buf.drv,255 ) ;
  2082.         if ( CDDA_NOW_status == CDDA_STAT_PLAY ||
  2083.                 CDDA_NOW_status == CDDA_STAT_PAUSE )
  2084.             cdr_continue( CDDA_INFO_buf.drv ) ;
  2085.  
  2086.     /*  ●●● STOP処理 ●●●    */
  2087.     case CDDA_SW_STOP :                            /*  強制停止                */
  2088. /*-----------------------------------------------------------------------------
  2089. **    プログラムモード時以外は、演奏停止する.
  2090. **    EJECT/EXIT(終了処理)時には、基本的には演奏を停止する.
  2091. **    ただし、オプション(CDDA_FLG_stopのこと)として演奏したまま終了できるようにし
  2092. **    てある.
  2093. **    停止指令がきて停止中であることを示すため CDDA_FLG_nowplay を クリア する.
  2094. -----------------------------------------------------------------------------*/
  2095.         CDDA_FLG_nowplay  = CDDA_FALSE ;
  2096.  
  2097. /*-----------------------------------------------------------------------------
  2098. **    プログラムモード時には、演奏中にSTOPされた時には、演奏を停止するだけであり、
  2099. **    停止状態の時にSTOPされた時には、プログラム設定された曲を クリア する.
  2100. -----------------------------------------------------------------------------*/
  2101.         if ( CDDA_PLAY_mode == CDDA_SW_PROGRAM &&
  2102.                 CDDA_NOW_status == CDDA_STAT_STOP ) {
  2103.             CDDA_music_clear() ;                /*  曲管理情報クリア            */
  2104.         }
  2105.  
  2106.         /*    ●● 演奏停止 ●●    */
  2107.         if ( CDDA_FLG_stop || mode == CDDA_SW_STOP ) CDDA_stop() ;
  2108.  
  2109.         /*  ●● 演奏モードにより処理が異なる ●●    */
  2110.         switch ( CDDA_PLAY_mode ) {
  2111.         /*  ●● SHUFFLE ●●    */
  2112.         case CDDA_SW_SHUFFLE :
  2113. /*-----------------------------------------------------------------------------
  2114. **    シャッフル演奏中にSTOPされた時には、CONTINUEモードに移行し、演奏を停止する.
  2115. -----------------------------------------------------------------------------*/
  2116.             CDDA_PLAY_mode = CDDA_SW_CONTINUE ;
  2117.             CDDA_nplay  = CDDA_ZERO ;                        /*  ポインタ        */
  2118.             for ( c=0; c<CDDA_MAX_TRACK; c++ ) {
  2119.                 if ( c < CDDA_INFO_buf.end )
  2120.                     CDDA_PLAY_no[c] = c+1 ;                    /*  曲番号        */
  2121.                 else
  2122.                     CDDA_PLAY_no[c] = CDDA_ZERO ;            /*  クリア            */
  2123.             }
  2124.             CDDA_NOW_end = CDDA_INFO_buf.end ;
  2125.             break ;
  2126.         /*  ●● PROGRAM ●●    */
  2127.         case CDDA_SW_PROGRAM :
  2128. /*-----------------------------------------------------------------------------
  2129. **    プログラム設定曲の確認をするための プログラムポインタ を クリア しておく.
  2130. -----------------------------------------------------------------------------*/
  2131.             CDDA_prgptr = CDDA_ZERO ;
  2132.             break ;            
  2133.         /*  ●● SINGLE / CONTINUE ●●    */
  2134.         case CDDA_SW_SINGLE :
  2135.         case CDDA_SW_CONTINUE :
  2136.             CDDA_nplay   = CDDA_ZERO ;                        /*  ポインタ        */
  2137.             CDDA_NOW_end = CDDA_INFO_buf.end ;
  2138.         }
  2139.     }
  2140. }
  2141.  
  2142. /*******************************  曲選択処理  ********************************/
  2143. int CDDA_select_music( int no )
  2144. /*=============================================================================
  2145. **    曲が選択された時の処理を行う.
  2146. **
  2147. **    < INPUT  > : 曲番号
  2148. **    < OUTPUT > : なし
  2149. **    < RETURN > : エラー値
  2150. =============================================================================*/
  2151. {
  2152.     int        c ;
  2153.  
  2154.     if ( CDDA_PLAY_mode == CDDA_SW_PROGRAM ) {
  2155. /*-----------------------------------------------------------------------------
  2156. **    プログラムモード時には、曲の追加のみ行う.
  2157. -----------------------------------------------------------------------------*/
  2158.         return( CDDA_program_data_add( no ) ) ;
  2159.     } else {
  2160. /*-----------------------------------------------------------------------------
  2161. **    指定された曲番号を演奏開始曲とする.
  2162. **    また、曲番号が指定された時は、プログラムモード時以外は、CONTINUEモードかSINGLE
  2163. **    モードの場合だけであるので、演奏ポインタ を更新しておく.
  2164. **    CONTINUEモードかSINGLEモードの時以外(プログラムモードを除く)は、CONTINUEモードに移行
  2165. **    してしまう.
  2166. -----------------------------------------------------------------------------*/
  2167.         CDDA_NOW_start = no ;
  2168.         CDDA_nplay   = no ;                                    /*  ポインタ        */
  2169. /*-----------------------------------------------------------------------------
  2170. **    他のモードから移行された時のために、演奏曲の格納をし直しておく.
  2171. -----------------------------------------------------------------------------*/
  2172.         for ( c=0; c<CDDA_MAX_TRACK; c++ ) {
  2173.             if ( c < CDDA_INFO_buf.end )
  2174.                 CDDA_PLAY_no[c] = c+1 ;                        /*  曲番号        */
  2175.             else
  2176.                 CDDA_PLAY_no[c] = CDDA_ZERO ;                /*  クリア            */
  2177.         }
  2178.  
  2179.         switch ( CDDA_PLAY_mode ) {
  2180.         case CDDA_SW_SHUFFLE :
  2181. /*-----------------------------------------------------------------------------
  2182. **    シャッフル演奏時には、CONTINUEモードに移行し、最後の曲まで演奏するようにする.
  2183. -----------------------------------------------------------------------------*/
  2184.             CDDA_PLAY_mode = CDDA_SW_CONTINUE ;
  2185.         case CDDA_SW_CONTINUE :
  2186.             CDDA_NOW_end = CDDA_INFO_buf.end ;
  2187.             break ;
  2188.         case CDDA_SW_SINGLE :
  2189. /*-----------------------------------------------------------------------------
  2190. **    SINGLEモード時には、演奏開始曲だけを演奏するように終了曲を設定する.
  2191. -----------------------------------------------------------------------------*/
  2192.             CDDA_NOW_end = no ;
  2193.         }
  2194.     }
  2195. /*-----------------------------------------------------------------------------
  2196. **    PAUSE中には、指定された曲から演奏開始できるように時間情報を設定しておく.
  2197. **    演奏はしないで、PAUSE状態を保持する. ただし、指定された曲の頭から演奏開始
  2198. **    できるようにする.
  2199. **
  2200. **    PAUSE中でなければ、指定された曲番号から演奏を開始する.
  2201. -----------------------------------------------------------------------------*/
  2202.     if ( CDDA_NOW_status == CDDA_STAT_PAUSE ) {
  2203. /*
  2204. **    PAUSE中ならば時間設定するだけ
  2205. */
  2206.         CDDA_FLG_pauseplay = CDDA_TRUE ;
  2207.         CDDA_NOW_musicno   = CDDA_NOW_pause = no ;
  2208. /*
  2209. **    演奏時間の指定
  2210. */
  2211.         CDDA_set_time_start( CDDA_NOW_start ) ;    /*  演奏開始曲データ設定    */
  2212.         CDDA_set_time_end( CDDA_NOW_end ) ;        /*  演奏終了曲データ設定    */
  2213. /*
  2214. **    現在の曲内経過時間
  2215. */
  2216.         CDDA_CLOCK_nowtrack.min   = CDDA_ZERO ;
  2217.         CDDA_CLOCK_nowtrack.sec   = CDDA_ZERO ;
  2218.         CDDA_CLOCK_nowtrack.frame = CDDA_ZERO ;
  2219.         memcpy( (char *)&CDDA_CLOCK_pause,(char *)&CDDA_CLOCK_nowtrack,
  2220.                 sizeof( CDDA_TRACK ) ) ;
  2221. /*
  2222. **    現在の残り時間
  2223. */
  2224.         CDDA_remaintime() ;
  2225.         return( CDDA_seek() ) ;
  2226.     } else {
  2227.         return( CDDA_play() ) ;
  2228.     }
  2229. }
  2230.  
  2231. /*******************************  モード選択処理  ******************************/
  2232. void CDDA_select_mode( int mode )
  2233. /*=============================================================================
  2234. **    演奏モードが選択された時の処理を行う.
  2235. **
  2236. **    < INPUT  > : 演奏モード
  2237. **    < OUTPUT > : なし
  2238. **    < RETURN > : なし
  2239. =============================================================================*/
  2240. {
  2241.     int        c ;
  2242.  
  2243. /*-----------------------------------------------------------------------------
  2244. **    各モードは、他のモードから移行してきた時だけ、モード毎の処理を行う.
  2245. -----------------------------------------------------------------------------*/
  2246.     switch ( mode ) {
  2247.     case CDDA_SW_PROGRAM :
  2248.         if ( CDDA_PLAY_mode != CDDA_SW_PROGRAM ) {
  2249.             CDDA_PLAY_mode = mode ;
  2250. /*-----------------------------------------------------------------------------
  2251. **    演奏曲番号 および プログラム曲の合計時間の クリア を行う.
  2252. -----------------------------------------------------------------------------*/
  2253.             CDDA_music_clear() ;                /*  曲管理情報クリア            */
  2254. /*-----------------------------------------------------------------------------
  2255. **    プログラムモード移行時に、演奏中またはPAUSE中ならば、その曲をプログラム登録して
  2256. **    しまう.
  2257. **    それ以外は、クリア 作業を行う.
  2258. -----------------------------------------------------------------------------*/
  2259.             if ( CDDA_NOW_status == CDDA_STAT_PLAY ||
  2260.                     CDDA_NOW_status == CDDA_STAT_PAUSE ) {
  2261.                 CDDA_nplay  = 1 ;
  2262.                 CDDA_NOW_start = CDDA_NOW_end = CDDA_NOW_musicno ;
  2263.                 CDDA_set_time_start( CDDA_NOW_start ) ;        /*  演奏開始    */
  2264. /*-----------------------------------------------------------------------------
  2265. **    PAUSE解除時に対応するための時間設定をする. 
  2266. -----------------------------------------------------------------------------*/
  2267.                 CDDA_addtime( CDDA_CLOCK_start.min,
  2268.                         CDDA_CLOCK_start.sec,
  2269.                         CDDA_CLOCK_start.frame,
  2270.                         CDDA_CLOCK_nowtrack.min,
  2271.                         CDDA_CLOCK_nowtrack.sec,
  2272.                         CDDA_CLOCK_nowtrack.frame,
  2273.                         &CDDA_CLOCK_start.min,
  2274.                         &CDDA_CLOCK_start.sec,
  2275.                         &CDDA_CLOCK_start.frame ) ;
  2276.                 CDDA_set_time_end( CDDA_NOW_end ) ;            /*  演奏終了    */
  2277.                 CDDA_program_data_add( CDDA_NOW_musicno ) ;
  2278.             }
  2279.         }
  2280.         break ;
  2281.     case CDDA_SW_CONTINUE :
  2282.     case CDDA_SW_SINGLE :
  2283.         if ( CDDA_PLAY_mode == mode ) break ;
  2284.         CDDA_PLAY_mode = mode ;
  2285. /*-----------------------------------------------------------------------------
  2286. **    CONTINUEモード,SINGLEモード時には、演奏中またはPAUSE中であれば、その曲を演奏
  2287. **    開始曲とする. そうでなければ、最初の曲を開始曲とする.
  2288. -----------------------------------------------------------------------------*/
  2289.         if ( CDDA_NOW_status == CDDA_STAT_PLAY ||
  2290.                 CDDA_NOW_status == CDDA_STAT_PAUSE ) {
  2291.             CDDA_NOW_start = CDDA_NOW_musicno ;
  2292.         } else if ( CDDA_NOW_status == CDDA_STAT_STOP ) {
  2293.             CDDA_NOW_start = CDDA_PLAY_no[0] ;
  2294.         }
  2295. /*-----------------------------------------------------------------------------
  2296. **    CONTINUEモード時でも、status取得後のチェックのために演奏終了曲を開始曲として
  2297. **    おく.
  2298. -----------------------------------------------------------------------------*/
  2299.         CDDA_NOW_end = CDDA_NOW_start ;
  2300.         CDDA_nplay   = CDDA_NOW_musicno ;                    /*  ポインタ        */
  2301.         CDDA_prgptr  = CDDA_ZERO ;
  2302. /*-----------------------------------------------------------------------------
  2303. **    他のモードから移行された時のために、演奏曲の格納をし直しておく.
  2304. -----------------------------------------------------------------------------*/
  2305.         for ( c=0; c<CDDA_MAX_TRACK; c++ ) {
  2306.             if ( c < CDDA_INFO_buf.end )
  2307.                 CDDA_PLAY_no[c] = c+1 ;                        /*  曲番号        */
  2308.             else
  2309.                 CDDA_PLAY_no[c] = CDDA_ZERO ;                /*  クリア            */
  2310.         }
  2311.         break ;
  2312.     case CDDA_SW_REPEAT :
  2313. /*-----------------------------------------------------------------------------
  2314. **    リピート指定は、停止時にリピート処理を行うための フラグ と リピート指定があったとい
  2315. **    う フラグ がある.
  2316. **    これは、各演奏モードにおいて、演奏状態をチェックする場合に意味を持つ.
  2317. **
  2318. **    リピート指定時もしくは、リピート指定後演奏状態またはPAUSE状態であれば、リピートを
  2319. **    有効にするという意味で、CDDA_FLG_repeaton を真値とする.
  2320. -----------------------------------------------------------------------------*/
  2321.         if ( CDDA_FLG_repeat ) {
  2322.             CDDA_FLG_repeat   = CDDA_FALSE ;
  2323.             CDDA_FLG_repeaton = CDDA_FALSE ;
  2324.         } else {
  2325.             CDDA_FLG_repeat   = CDDA_TRUE ;
  2326.             CDDA_FLG_repeaton = CDDA_FALSE ;
  2327.             if ( CDDA_NOW_status == CDDA_STAT_PLAY ||
  2328.                     CDDA_NOW_status == CDDA_STAT_PAUSE )
  2329.                 CDDA_FLG_repeaton = CDDA_TRUE ;
  2330.         }
  2331.     }
  2332. }
  2333.  
  2334. /*******************************  演奏選択処理  ******************************/
  2335. int CDDA_select_play( void )
  2336. /*=============================================================================
  2337. **    演奏が選択された時の処理を行う.
  2338. **
  2339. **    < INPUT  > : なし
  2340. **    < OUTPUT > : なし
  2341. **    < RETURN > : なし
  2342. **
  2343. **    演奏中に演奏命令が来ても、無効とする.
  2344. **    ただし、シャッフル演奏時には、シャッフル演奏を無効とし、CONTINUEモードに移行する.
  2345. **    PAUSE中であれば、PAUSEの解除を行う.
  2346. =============================================================================*/
  2347. {
  2348.     int        ret ;
  2349.     int        c ;
  2350.  
  2351.     ret = CDDA_ERR_NOERROR ;
  2352.     if ( CDDA_PLAY_mode == CDDA_SW_SHUFFLE ) {
  2353. /*-----------------------------------------------------------------------------
  2354. **    停止中または演奏中の状態が、シャッフルモードによるものならば、CONTINUEモードに移行
  2355. **    する. そのために、曲番号の管理領域を リセット しておく.
  2356. -----------------------------------------------------------------------------*/
  2357.         switch ( CDDA_NOW_status ) {
  2358.         case CDDA_STAT_STOP :
  2359.         case CDDA_STAT_PLAY :
  2360.             for ( c=0; c<CDDA_MAX_TRACK; c++ ) {
  2361.                 if ( c < CDDA_INFO_buf.end )
  2362.                     CDDA_PLAY_no[c] = c+1 ;                /*  曲番号        */
  2363.                 else
  2364.                     CDDA_PLAY_no[c] = CDDA_ZERO ;        /*  クリア            */
  2365.             }
  2366.         }
  2367.     }
  2368.  
  2369. /*    ●●● 演奏モードにより処理が異なる ●●●    */
  2370.     switch ( CDDA_PLAY_mode ) {
  2371.     case CDDA_SW_PROGRAM :
  2372. /*-----------------------------------------------------------------------------
  2373. **    プログラムモード時には、停止中であれば、プログラム登録してある曲のうち 演奏済で
  2374. **    ない曲から演奏を開始する.
  2375. -----------------------------------------------------------------------------*/
  2376.         switch ( CDDA_NOW_status ) {
  2377.         case CDDA_STAT_STOP :
  2378.             if ( CDDA_nplay > CDDA_ZERO ) {
  2379.                 CDDA_NOW_start = CDDA_PLAY_no[CDDA_nplay-1] ;
  2380.                 CDDA_NOW_end   = CDDA_PLAY_no[CDDA_nplay-1] ;
  2381.             } else {
  2382.                 CDDA_NOW_start = CDDA_NOW_end = CDDA_PLAY_no[CDDA_ZERO] ;
  2383.             }
  2384.             ret = CDDA_play() ;
  2385.             break ;
  2386.         case CDDA_STAT_PAUSE :
  2387. /*-----------------------------------------------------------------------------
  2388. **    PAUSE中であれば、PAUSEを解除する.
  2389. -----------------------------------------------------------------------------*/
  2390.             CDDA_FLG_pauseplay = CDDA_TRUE ;
  2391.             ret = CDDA_pause() ;
  2392.             break ;
  2393.         case CDDA_STAT_PLAY :
  2394. /*-----------------------------------------------------------------------------
  2395. **    演奏中は、無視し、演奏中である旨の エラー値 を返す.
  2396. -----------------------------------------------------------------------------*/
  2397.             ret = CDDA_ERR_NOWPLAY ;
  2398.         }
  2399.         break ;
  2400. /*-----------------------------------------------------------------------------
  2401. **    ●●● プログラムモード以外 ●●●
  2402. -----------------------------------------------------------------------------*/
  2403.     default :
  2404. /*-----------------------------------------------------------------------------
  2405. **    プログラムモード以外では、停止中であれば、最初の曲から演奏を行う.
  2406. -----------------------------------------------------------------------------*/
  2407.         switch ( CDDA_NOW_status ) {
  2408.         case CDDA_STAT_STOP :
  2409.             CDDA_nplay   = CDDA_ZERO ;                /*  ポインタ        */
  2410. /*-----------------------------------------------------------------------------
  2411. **    シャッフル状態のままならば、CONTINUEモードに移行し演奏するようにする.
  2412. -----------------------------------------------------------------------------*/
  2413.             if ( CDDA_PLAY_mode == CDDA_SW_SHUFFLE ) {
  2414.                 CDDA_PLAY_mode = CDDA_SW_CONTINUE ;
  2415.             }
  2416.             CDDA_NOW_start = CDDA_PLAY_no[CDDA_ZERO] ;
  2417.             CDDA_NOW_end   = CDDA_NOW_start ;
  2418.             if ( CDDA_PLAY_mode == CDDA_SW_CONTINUE )
  2419.                 CDDA_NOW_end   = CDDA_INFO_buf.end ;
  2420.             ret = CDDA_play() ;
  2421.             break ;
  2422.         case CDDA_STAT_PAUSE :
  2423. /*-----------------------------------------------------------------------------
  2424. **    PAUSE中であれば、PAUSEを解除する.
  2425. -----------------------------------------------------------------------------*/
  2426.             ret = CDDA_pause() ;
  2427.             break ;
  2428.         case CDDA_STAT_PLAY :
  2429. /*-----------------------------------------------------------------------------
  2430. **    演奏中は、無視し、演奏中である旨の エラー値 を返す.
  2431. **    ただし、シャッフル演奏中ならば、CONTINUEモードに移行する.
  2432. -----------------------------------------------------------------------------*/
  2433.             if ( CDDA_PLAY_mode == CDDA_SW_SHUFFLE ) {
  2434.                 CDDA_PLAY_mode = CDDA_SW_CONTINUE ;
  2435.                 CDDA_NOW_start = CDDA_NOW_musicno ;
  2436.                 CDDA_nplay     = CDDA_NOW_musicno ;        /*  ポインタ        */
  2437. /*  モード移行時のチェックのため    */
  2438. /*-----------------------------------------------------------------------------
  2439. **    シャッフル演奏時は、一曲演奏なので、CONTINUEモードに移行した時の演奏状態チェックの
  2440. **    ために、演奏終了曲を今演奏中の曲番号としておく.
  2441. -----------------------------------------------------------------------------*/
  2442.                 ret = CDDA_ERR_NOERROR ;
  2443.             } else {
  2444. /*-----------------------------------------------------------------------------
  2445. **    演奏中は、無視し、演奏中である旨の エラー値 を返す.
  2446. -----------------------------------------------------------------------------*/
  2447.                 ret = CDDA_ERR_NOWPLAY ;
  2448.             }
  2449.             break ;
  2450.         default :
  2451.             CDDA_libinit() ;
  2452.             ret = CDDA_ERR_NOTREADY ;
  2453.             break ;
  2454.         }
  2455.     }
  2456.     return( ret ) ;
  2457. }
  2458.  
  2459. /*****************************  シャッフル演奏選択処理  ***************************/
  2460. int CDDA_select_shuffle( void )
  2461. /*=============================================================================
  2462. **    シャッフル演奏が選択された時の処理を行う.
  2463. **
  2464. **    < INPUT  > : なし
  2465. **    < OUTPUT > : なし
  2466. **    < RETURN > : なし
  2467. **
  2468. **    あらたにシャッフルしなおして、演奏を開始する.
  2469. =============================================================================*/
  2470. {
  2471.     int        ret ;
  2472.  
  2473.     ret = CDDA_ERR_NOERROR ;
  2474. /*-----------------------------------------------------------------------------
  2475. **    シャッフル演奏を開始させようとして、演奏曲がなかった場合には、音楽なしのエラー値
  2476. **    を返す.
  2477. **    PAUSE中であれば、シャッフル演奏をする準備だけし、PAUSE状態を保持する.
  2478. -----------------------------------------------------------------------------*/
  2479.     CDDA_PLAY_mode = CDDA_SW_SHUFFLE ;
  2480.     CDDA_FLG_shuffleinit = CDDA_TRUE ;
  2481.     if ( !CDDA_shuffle( &CDDA_NOW_start ) ) {
  2482.         CDDA_NOW_end = CDDA_NOW_start ;
  2483.         if ( CDDA_FLG_pause ) {            /*  PAUSE中                    */
  2484.             CDDA_FLG_pauseplay = CDDA_TRUE ;
  2485.             if ( CDDA_FLG_ffrew && CDDA_FLG_ffrewpause ) {
  2486.                 ret = CDDA_play() ;
  2487.             } else {                    /*  時間設定するだけ        */
  2488.                 CDDA_set_time_start( CDDA_NOW_start ) ;
  2489.                 CDDA_set_time_end( CDDA_NOW_end ) ;
  2490.             }
  2491.         } else {
  2492.             ret = CDDA_play() ;
  2493.         }
  2494.     } else {
  2495.         if ( CDDA_NOW_status == CDDA_STAT_NOTREADY )
  2496.             ret = CDDA_ERR_NOTREADY ;
  2497.         else
  2498.             ret = CDDA_ERR_NOMUSIC ;
  2499.     }
  2500.  
  2501.     return( ret ) ;
  2502. }
  2503.  
  2504. /*******************************  プログラム操作処理  ***************************/
  2505. int CDDA_select_program( int mode )
  2506. /*=============================================================================
  2507. **    プログラムによる曲の確認/削除の処理を行う.
  2508. **
  2509. **    < INPUT  > : プログラムスイッチ
  2510. **    < OUTPUT > : なし
  2511. **    < RETURN > : 曲番号
  2512. =============================================================================*/
  2513. {
  2514.     switch ( mode ) {
  2515.     /*    ●● プログラム確認 ●●    */
  2516.     case CDDA_SW_PRG_CHECK :
  2517.         CDDA_COUNT_program = CDDA_ZERO ;
  2518.         if ( CDDA_PLAY_mode != CDDA_SW_PROGRAM ) return( CDDA_ZERO ) ;
  2519.         if ( CDDA_NOW_status == CDDA_STAT_NOTREADY )
  2520.             return( CDDA_ZERO ) ;
  2521.         return( CDDA_program_data_check() ) ;
  2522.  
  2523.     /*    ●● プログラム1曲削除 ●●    */
  2524.     case CDDA_SW_PRG_CLEAR :
  2525.         CDDA_COUNT_program = CDDA_ZERO ;
  2526.         if ( CDDA_PLAY_mode != CDDA_SW_PROGRAM ) return( CDDA_ZERO ) ;
  2527.         if ( CDDA_NOW_status == CDDA_STAT_NOTREADY )
  2528.             return( CDDA_ZERO ) ;
  2529.         return( CDDA_program_data_clear() ) ;
  2530.  
  2531.     /*  ●● プログラム確認/削除ポインタのクリア ●●    */
  2532.     case CDDA_SW_PRG_TOP :
  2533. /*-----------------------------------------------------------------------------
  2534. **    プログラムポインタ を クリア する.
  2535. -----------------------------------------------------------------------------*/
  2536.         CDDA_prgptr = CDDA_ZERO ;
  2537.         return( CDDA_ERR_NOERROR ) ;
  2538.     }
  2539. }
  2540.  
  2541. /*******************************  演奏スイッチ処理  ******************************/
  2542. int CDDA_switch( int mode )
  2543. /*=============================================================================
  2544. **    CDプレーヤのインターフェース(スイッチ相当)処理を行う.
  2545. **
  2546. **    < INPUT  > : モード(スイッチ) か 曲番号
  2547. **    < OUTPUT > : なし
  2548. **    < RETURN > : エラー値( プログラム時には 曲番号 , 終了時は 0 )
  2549. =============================================================================*/
  2550. {
  2551.     int        ret ;
  2552.  
  2553.     if ( !CDDA_FLG_libinit ) CDDA_libinit() ;
  2554.  
  2555.     switch ( mode ) {
  2556.     /*  ●● 初期処理 ●●    */
  2557.     case CDDA_SW_INIT :
  2558.         return( CDDA_swinit() ) ;
  2559.     /*    ●● プログラムポインタのクリア ●●    */
  2560.     case CDDA_SW_PRG_TOP :
  2561.         CDDA_prgptr = CDDA_ZERO ;
  2562.         return( CDDA_ERR_NOERROR ) ;
  2563.     /*  ●● ステータス取得 ●●    */
  2564.     case CDDA_SW_STATUS :
  2565.         return( CDDA_status() ) ;
  2566.     /*    ●● ステータスチェック ●●    */
  2567.     default :
  2568.         if ( !CDDA_FLG_ffrew ) {        /*  FF/REW中でなければ...    */
  2569.             ret = CDDA_status() ;
  2570.             if ( ret ) return( ret ) ;
  2571.         }
  2572.     }
  2573.  
  2574. /*-----------------------------------------------------------------------------
  2575. **    フラグクリア処理
  2576. -----------------------------------------------------------------------------*/
  2577.     switch ( mode ) {
  2578.     case CDDA_SW_FFMUSIC :
  2579.     case CDDA_SW_REWMUSIC :
  2580.     case CDDA_SW_FFTIME :
  2581.     case CDDA_SW_REWTIME :
  2582. /*-----------------------------------------------------------------------------
  2583. **    先送り/後戻り処理は、演奏中かPAUSE中以外は、無効とする.
  2584. -----------------------------------------------------------------------------*/
  2585.         if ( CDDA_NOW_status != CDDA_STAT_PLAY &&
  2586.                 CDDA_NOW_status != CDDA_STAT_PAUSE )
  2587.             return( CDDA_ERR_PARAMETER ) ;
  2588.     case CDDA_SW_PAUSE :
  2589.     case CDDA_SW_SHUFFLE :
  2590.         break ;
  2591.     default :
  2592. /*-----------------------------------------------------------------------------
  2593. **    先送り/後戻り時に、最後に スイッチ を放したという命令がこなくても他の スイッチ が
  2594. **    押された時には、先送り/後戻りの終了とする.
  2595. **
  2596. **    ただし、PAUSE / SHUFFLE スイッチ は、FF/REW 中でも有効とする.
  2597. -----------------------------------------------------------------------------*/
  2598.         if ( CDDA_FLG_ffrew && CDDA_FLG_ffrewpause ) {
  2599.             /*  FF/REW中でPAUSEした時    */
  2600.             ret = CDDA_pause() ;
  2601.         }
  2602.         CDDA_FLG_ffrew      = CDDA_FALSE ;
  2603.         CDDA_FLG_ffrewpause = CDDA_FALSE ;
  2604.     }
  2605.  
  2606. /*-----------------------------------------------------------------------------
  2607. **    演奏終了処理
  2608. -----------------------------------------------------------------------------*/
  2609.     switch ( mode ) {
  2610.     case CDDA_SW_EJECT :
  2611. /*    case CDDA_SW_EXIT :    は CDDA_SW_EJECT と同じ    */
  2612.     case CDDA_SW_STOP :
  2613.         CDDA_select_stop( mode ) ;
  2614.         return( ret ) ;
  2615.     }
  2616.  
  2617. /*    ●●●●●  演奏スイッチ処理  ●●●●●    */
  2618.     if ( mode > CDDA_MAX_TRACK ) {
  2619. /*-----------------------------------------------------------------------------
  2620. **    演奏処理
  2621. -----------------------------------------------------------------------------*/
  2622.         switch ( mode ) {
  2623.         /*  ●● TOC 読み込み ●●    */
  2624.         case CDDA_SW_TOCREAD :
  2625.             if ( CDDA_tocread() ) return( CDDA_ERR_NOTREADY ) ;
  2626.             return( CDDA_ERR_NOERROR ) ;
  2627.         /*  ●● PAUSE ●●    */
  2628.         case CDDA_SW_PAUSE :
  2629. /*-----------------------------------------------------------------------------
  2630. **    FF/REW の スイッチ ON の時には、必ず停止状態とするために、現在のPAUSE状態が
  2631. **    FF/REW によるものか元々PAUSE状態だっものかを見分ける必要がある.
  2632. **    そのために ffrewpause フラグ を使用している.
  2633. -----------------------------------------------------------------------------*/
  2634.             if ( CDDA_FLG_ffrew ) {                /*  FF/REW中                */
  2635.                 CDDA_FLG_ffrew = CDDA_FALSE ;
  2636.                 if ( CDDA_FLG_ffrewpause ) {    /*  FF/REW中でPAUSEした時    */
  2637.                     CDDA_FLG_ffrewpause = CDDA_FALSE ;
  2638.                 } else {                        /*  元々PAUSE中だった時        */
  2639.                     ret = CDDA_pause() ;
  2640.                 }
  2641.             } else {                            /*  通常                    */
  2642.                 ret = CDDA_pause() ;
  2643.             }
  2644.             return( ret ) ;
  2645.         /*  ●● PLAY ●●    */
  2646.         case CDDA_SW_PLAY :
  2647.             return( CDDA_select_play() ) ;
  2648.         /*    ●● SHUFFLE ●●    */
  2649.         case CDDA_SW_SHUFFLE :
  2650.             CDDA_FLG_ffrew      = CDDA_FALSE ;
  2651.             CDDA_FLG_ffrewpause = CDDA_FALSE ;
  2652.             return( CDDA_select_shuffle() ) ;
  2653.         }
  2654.  
  2655. /*-----------------------------------------------------------------------------
  2656. **    プログラム処理
  2657. -----------------------------------------------------------------------------*/
  2658.         switch ( mode ) {
  2659.         case CDDA_SW_PRG_CHECK :
  2660.         case CDDA_SW_PRG_CLEAR :
  2661. /*        case CDDA_SW_PRG_TOP :    status を 取得する必要なしのため,
  2662.                                 先頭にて処理する.                            */
  2663.             return( CDDA_select_program( mode ) ) ;
  2664.         }
  2665.  
  2666. /*-----------------------------------------------------------------------------
  2667. **    先送り/後戻り時の前後処理
  2668. -----------------------------------------------------------------------------*/
  2669.         switch ( mode ) {
  2670.         case CDDA_SW_FFMUSIC :
  2671.         case CDDA_SW_REWMUSIC :
  2672.         case CDDA_SW_FFTIME :
  2673.         case CDDA_SW_REWTIME :
  2674. /*-----------------------------------------------------------------------------
  2675. **    FF/REW 時には、必ずPAUSE状態でなければならないため、FF/REW 開始時/終了時
  2676. **    には、PAUSE処理をしておく必要がある.
  2677. -----------------------------------------------------------------------------*/
  2678.             if ( CDDA_NOW_status == CDDA_STAT_PLAY ||
  2679.                     CDDA_NOW_status == CDDA_STAT_PAUSE ) {
  2680.                 if ( !CDDA_FLG_ffrew ) {            /*  FF/REW中でない時    */
  2681.                     CDDA_FLG_ffrew      = CDDA_TRUE ;
  2682.                     CDDA_FLG_ffrewpause = CDDA_FALSE ;
  2683.                     if ( !CDDA_FLG_pause ) {        /*  PAUSE中でない時        */
  2684.                         CDDA_FLG_ffrewpause = CDDA_TRUE ;
  2685.                         ret = CDDA_pause() ;
  2686.                     }
  2687.                 }
  2688.             } else {
  2689.                 CDDA_FLG_ffrew      = CDDA_FALSE ;
  2690.                 CDDA_FLG_ffrewpause = CDDA_FALSE ;
  2691.             }
  2692.             break ;
  2693.         }
  2694. /*-----------------------------------------------------------------------------
  2695. **    先送り/後戻り処理( return )
  2696. -----------------------------------------------------------------------------*/
  2697.         switch ( mode ) {
  2698.         case CDDA_SW_FFMUSIC :
  2699.             return( CDDA_ffmusic() ) ;
  2700.         case CDDA_SW_REWMUSIC :
  2701.             return( CDDA_rewmusic() ) ;
  2702.         case CDDA_SW_FFTIME :
  2703.             return( CDDA_fftime() ) ;
  2704.         case CDDA_SW_REWTIME :
  2705.             return( CDDA_rewtime() ) ;
  2706.         }
  2707. /*-----------------------------------------------------------------------------
  2708. **    モード設定
  2709. -----------------------------------------------------------------------------*/
  2710.         switch ( mode ) {
  2711.         case CDDA_SW_PROGRAM :
  2712.         case CDDA_SW_CONTINUE :
  2713.         case CDDA_SW_SINGLE :
  2714.         case CDDA_SW_REPEAT :
  2715.             CDDA_select_mode( mode ) ;
  2716.             return( CDDA_ERR_NOERROR ) ;
  2717.         }
  2718.     }
  2719.  
  2720. /*-----------------------------------------------------------------------------
  2721. **    曲番号指定による演奏
  2722. -----------------------------------------------------------------------------*/
  2723.     if ( mode < CDDA_INFO_buf.start || mode > CDDA_INFO_buf.end )
  2724.         return( CDDA_ERR_PARAMETER ) ;
  2725.  
  2726.     CDDA_FLG_ffrew      = CDDA_FALSE ;
  2727.     CDDA_FLG_ffrewpause = CDDA_FALSE ;
  2728.  
  2729.     return( CDDA_select_music( mode ) ) ;
  2730. }
  2731.  
  2732. /*******************************  演奏モード取得  ******************************/
  2733. int CDDA_get_playmode( void )
  2734. /*=============================================================================
  2735. **    現在の演奏モードを取得する.
  2736. **
  2737. **    < INPUT  > : なし
  2738. **    < OUTPUT > : なし
  2739. **    < RETURN > : 演奏モード値
  2740. =============================================================================*/
  2741. {
  2742.     return( CDDA_PLAY_mode ) ;
  2743. }
  2744.  
  2745. /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
  2746.  
  2747. #undef    _CDDA_LIB
  2748.  
  2749. /*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
  2750.  
  2751. /*******************************  デバッグ用  ********************************/
  2752. void CDDA_debug_dispmsg( int errno )
  2753. /*=============================================================================
  2754. **    デバッグ用にメッセージIDに対応したメッセージを出力する.
  2755. **
  2756. **    < INPUT  > : エラー値
  2757. **    < OUTPUT > : なし
  2758. **    < RETURN > : なし
  2759. =============================================================================*/
  2760. {
  2761.     char    *CDDA_ERR_msg[] = {
  2762.             "正常終了.",                                    /*  000(0x000)    */
  2763.             "CDがセットされていません.",                    /*  001(0x001)    */
  2764.             "パラメタに誤りがあります.",                    /*  002(0x002)    */
  2765.             "CDドライブが接続されていません.",            /*  004(0x004)    */
  2766.             "コマンドが異常終了しました.",                    /*  008(0x008)    */
  2767.             "メディアエラー.",                                /*  016(0x010)    */
  2768.             "ハードエラー.",                                /*  032(0x020)    */
  2769.             "パリティエラー.",                                /*  064(0x040)    */
  2770.             "メディアが交換されてます.",                    /*  128(0x080)    */
  2771.             "デバイス番号に誤りがあります.",                /*  256(0x100)    */
  2772.             "セクタ長が違います.",                            /*  257(0x101)    */
  2773.             "音楽演奏中です.",                                /*  258(0x102)    */
  2774.             "一時停止中です.",                                /*  260(0x104)    */
  2775.             "一時停止状態ではありません.",                    /*  264(0x108)    */
  2776.             "音楽データがありません.",                        /*  272(0x110)    */
  2777.             "繰り返し演奏を開始しました.",                    /*  288(0x120)    */
  2778.             "該当メッセージなし."                            /*  ---(0x---)    */
  2779.             } ;
  2780.     char    *CDDA_STATUS_msg[] = {
  2781.             "CDがセットされていません.",
  2782.             "停止中です.",
  2783.             "演奏中です.",
  2784.             "一時停止中です."
  2785.             } ;
  2786.     int        c, chk, no ;
  2787.     int        nomsg = 16 ;
  2788.  
  2789.     chk = 0x0001 ;
  2790.     no = 0 ;
  2791.     for ( c=0; c<8; c++ ) {
  2792.         if ( ((errno & 0x00ff) & chk) == chk ) no = c + 1 ;
  2793.         chk <<= 1 ;
  2794.     }
  2795.     if ( errno > 255 ) no += 9 ;
  2796.     if ( errno != 0 && no == 0 ) no = nomsg ;
  2797.     if ( no < 0 || no > nomsg ) no = nomsg ;
  2798.     printf( "CDDA DEBUG MSG (%04xh) : %s\n",errno,CDDA_ERR_msg[no] ) ;
  2799.     no = CDDA_NOW_status ;
  2800.     if ( no < 0 ) {
  2801.         no = 0 ;
  2802.     } else {
  2803.         no ++ ;
  2804.     }
  2805.     printf( "Now status (%d) : %s\n",CDDA_NOW_status,CDDA_STATUS_msg[no] ) ;
  2806. }
  2807.  
  2808.